home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / COMMUNIC / 1572A.ZIP / KMT_IBM3.ZIP / MSYIBM.ASM < prev   
Assembly Source File  |  1989-07-11  |  120KB  |  2,387 lines

  1. ; File MSYIBM.ASM
  2. ; edit history:
  3. ; Last edit 21 Jan 1989
  4. ; 21 Jan 1989 be more tolerate of propriatary video modes above 18 when
  5. ;  determining screen segment, Tnx to Terry Kennedy. Add check for IBM
  6. ;  85xx monitors on Video 7 boards, no 132 columns if it is the monitor.
  7. ;  Retain 43 rows on Video 7 boards.
  8. ; 30 Nov 1988 Add SET TERM CLEAR screen clearing support.
  9. ; 28 Nov 1988 Accomodate Tseng Labs UltraPAK mono/Herc board w/132 cols.
  10. ;  132 column mode is 18h. Requires Tseng's BIGSCR.COM (use BIGSCR /R:25
  11. ;  to enable 132x25 feature). Thanks to Tseng Labs for technical support.
  12. ; 21 Nov 1988 Version 2.32
  13. ; 14 Nov 1988 Write a space during lclini to obtain default screen colors.
  14. ; 12 Nov 1988 Add procs vtrmac and vtsmac to allow exit from Connect mode and
  15. ;  invokation of macros TERMINALR and TERMINALS by reception of escape seqs
  16. ;  in file mszibm.asm or by keyboard verbs.
  17. ; 7 Oct 1988 Reverse left/right arrow key codes when writing right to left.
  18. ; 24 Sept 1988 Make output to printer be buffered and flow controlled.
  19. ; 1 July 1988 Version 2.31
  20. ; 19 June 1988 Add Everex EVGA support, from Terry Kennedy.
  21. ; 10 June 1988 Add oldsp and procedure endcon to exit Connect mode if output
  22. ;  fails, mostly for networking (but we don't know that here).
  23. ; 23 May 1988 Add Everex EV-659 ega board test from Alex Zliu. Fixed incorrect
  24. ;  screen width assumption at startup.
  25. ; 29 March 1988 Include flag ttyact to group string bytes into one net packet,
  26. ;  thanks to Paul Fox of AT&T.
  27. ; 23 March 1988 Add "fairness" word to let serial port deliver max chars
  28. ;  between kbd reads, for connect mode only. [jrd]
  29. ; 10 Feb 1988 Revise getcirc and vtscrX routines to do proper scrolling with
  30. ;  MS Window 1.0x/2.0x [jrd].
  31. ; 9 Feb 1988 Mode line again. Make flags.modflg 0 for off, 1 for on and owned
  32. ;  by Kermit, and 2 for on and owned by remote host (toggling suppressed).
  33. ; 25 Jan 1988 Add global byte SCROLL, set in msz, to control emulator screen
  34. ;  scrolling for higher speeds. [jrd]
  35. ; 5 Jan 1988 Restore cursor codes broken by Tek code additions. [jrd]
  36. ; 1 Jan 1988 version 2.30
  37.  
  38.         public  term, lclyini                           ; entry points
  39.         public  prtbout, prtnout, csrtype, scrmod, scrseg, scrsync
  40.         public  scroff, scron, atsclr, vtscru, vtscrd, scrloc, trnmod, telmsy
  41.         public  chgdsp, vtroll, crt_lins, crt_cols, getflgs, tv_mode, vtclear
  42.                         ; action verb procedures for keyboard translator
  43.         public  uparrw, dnarrw, rtarr, lfarr, pf1, pf2, pf3, pf4
  44.         public  kp0, kp1, kp2, kp3, kp4, kp5, kp6, kp7, kp8, kp9
  45.         public  kpminus, kpcoma, kpenter, kpdot, chrout, cstatus, cquit
  46.         public  cquery, dmpscn, vtans52, vtinit, dnwpg, upwpg, endwnd, homwnd
  47.         public  upone, dnone, trnprs, dumpscr, modlin, modwrt, snull
  48.         public  klogon, klogof, cdos, chang, khold, vtrmac, vtsmac
  49.  
  50.         public  vtemu, crt_mode, scbattr, refresh, low_rgt      ; data
  51.         public  savescr, restscr, pntchr, pntchk, pntflsh       ; code
  52.         include mssdef.h
  53.  
  54. ; some definitions
  55. ; hardware
  56. crt_status equ  3dah                    ; CGA crt status port
  57. disp_enb equ    8                       ; CGA display enable bit
  58. crtmset equ     3D8H                    ; CGA CRT mode set port
  59. screen  equ     10h                     ; Bios screen interrupt
  60. biostty equ     0eh                     ; Bios screen tty write mode
  61.  
  62. modfrm  struc                           ; format of mode (status) line
  63.         db      'Esc-chr: '             ; do not write in last column
  64. m_echr  db      2 dup (?)
  65.         db      '  help: '
  66. m_hlp   db      2 dup (?)
  67.         db      '?  port:'
  68. m_prt   db      1 dup (?)
  69.         db      ' speed:'
  70. m_baud  db      5 dup (?)
  71.         db      ' parity:'
  72. m_par   db      4 dup (?)
  73.         db      ' echo:'
  74. m_echo  db      3 dup (?)
  75. m_term  db      13 dup (' ')            ; 13 bytes for term type
  76. m_prn   db      3 dup (' ')             ; show PRN when printer is on
  77. modfrm  ends
  78.  
  79.  
  80. datas   segment public 'datas'
  81.         extrn flags:byte, mar_top:byte, mar_bot:byte, portval:word
  82.         extrn filtst:byte, dmpname:byte, kbdflg:byte, rxtable:byte
  83.         extrn anspflg:byte, tekflg:byte, scroll:byte, ttyact:byte
  84.         extrn holdscr:byte, taklev:byte, takadr:word, mcctab:byte
  85.  
  86. ; stuff for screen routines
  87. yflags  db      0                       ; status flags
  88. flags1  db      0                       ; internal flags (but used in mszibm)
  89. prtscr  equ     1                       ; print screen pressed
  90. inited  equ     08h                     ; been here before
  91. vtinited db     0                       ; flag for emulator having been inited
  92. vtclear db      0                       ; nonzero to clear emulator screen
  93. cursor  dw      0
  94. esc_ch  db      0
  95. parmsk  db      0                       ; 8/7 bit parity mask, for reception
  96. argadr  dw      ?                       ; address of arg blk
  97.  
  98. vid7id  db      'VEGA BIOS Code, '      ; Video 7 Vega version string subset
  99. vid7len equ     $-vid7id                ; length of string
  100. vid7id2 db      'Video Seven BIOS Code, ' ; Video 7 VGA board
  101. vid7len2 equ    $-vid7id2
  102. atiwid  db      'ATI EGA Wonder Bios,'  ; ATI EGA wonder version string subset
  103. atilen  equ     $-atiwid                ; length of string, inc terminator
  104. tsngid  db      'Tseng'                 ; Tseng Labs EVA (& Orchid Designer)
  105. tsnglen equ     $-tsngid
  106. evrxid  db      'Everex'                ; Everex Micro Enhancer Deluxe EGA
  107. evrxlen equ     $-evrxid
  108. evgid   db      'VGA EV673'             ; Everex EVGA EV-673
  109. evglen  equ     $-evgid
  110. ega_mode db     0                       ; non-zero if IBM EGA is in use
  111. tvhere  equ     0feh                    ; Topview active query
  112. tvsynch equ     0ffh                    ; Topview resynch request
  113. tv_segs dw      ?                       ; Topview virtual screen, segment
  114. tv_sego dw      ?                       ; and offset
  115. tv_mode db      0                       ; flag, 0 = no Topview
  116. savadr  dw      2 dup (?)               ; offset then segment of saved screen
  117. savflg  dw      0                       ; low_rgt at time of screen save
  118.  
  119. ; The following are used to turn the display back on (after scrolling etc.)
  120. msets   db      2CH,28H,2DH,29H,2AH,2EH,1EH,29H
  121.  
  122.  
  123. vtemu   emulst  <>                      ; emulator flags
  124. ansflgs db      0                       ; ANSI flags
  125. trmtyp  db      0                       ; most recent terminal type
  126. mtty    db      '  TTY   '              ; no terminal type (mode line)
  127. fairness dw     0
  128. lincur  dw      ?                       ; cursor type save area
  129. scbattr db      ?                       ; Screen background attribute
  130. oldattr db      ?                       ; screen attributes at init time
  131. curattr db      ?                       ; current attribute
  132. oldsp   dw      0                       ; offset to longjmp to for i/o failure
  133. temp    dw      ?                       ; scratch storage
  134. modtemp db      0                       ; temp to hold Kermit modeline status
  135. captrtn dw      ?                       ; routine to call for captured output
  136. dmphand dw      -1                      ; screen dump file handle
  137. dumplen equ     132
  138. dumpbuf db      dumplen dup (?), cr, lf ; 134 byte dump work buffer
  139. dumpsep db      FF,cr,lf                ; screen image separators
  140. dmperr  db      ' Cannot open file to save screen to disk $'
  141. crlf    db      cr,lf,'$'
  142. flowon  db      0                       ; flow control chars xon
  143. flowoff db      0                       ;  and xoff (or both null if none)
  144. pntmsg  db      'Printer not ready, printing request skipped.'
  145. pntmsgl equ     $-pntmsg                ; length of pntmsg
  146. pntptr  dw      dumpbuf                 ; pointer to next free byte in buffer
  147.  
  148. ; some static data for mode line
  149. modbuf  modfrm  <>                      ; mode line buffer
  150. unkbaud db      'unkwn'                 ; must be 5 chars
  151. baudn   db      ' 45.5',' 50  ',' 75  ',' 110 ','134.5',' 150 ',' 300 ',' 600 '
  152.         db      ' 1200',' 1800',' 2000',' 2400',' 4800',' 9600','19200','38400'
  153.         db      '57.6K','115 K'
  154. baudnsiz  equ   18                      ; # of baud rates known (tbl size / 4)
  155. parnams db      'even','mark','none','odd ','spc '
  156. lclmsg  db      'loc'
  157. remmsg  db      'rem'
  158. portno  db      ?
  159.  
  160. ; storage for multi-window stuff
  161. swidth  equ     80                      ; max screen width
  162. slen    equ     24                      ; and length of text
  163. npages  equ     10                      ; # of pages of scrolling on each side
  164. crt_norm db     ?                       ; video mode for normal screen
  165. crt_mode db     ?                       ; video mode (typ 3, must be text)
  166. crt_cols db     ?                       ; number of screen columns (typ 80)
  167. crt_lins db     24                      ; number of screen rows - 1 (typ 24)
  168. low_rgt dw      ?                       ; lower right corner of text window
  169.                                         ; high = row address (typ 23)
  170.                                         ; low = column address (typ 79)
  171. inipara dw      ?                       ; initial paragraphs of scroll memory
  172. scrsav  dw      ?                       ; segment address of save area
  173. refresh db      0                       ; screen refresh (0=wait for retrace)
  174. vtroll  db      0                       ; auto roll back allowed (0 = no)
  175.  
  176. ; circular buffer for screen roll back.
  177. cbuf    struc
  178. pp      dw      ?                       ; place ptr in buffer
  179. bend    dw      ?                       ; end of buffer
  180. orig    dw      ?                       ; buffer origin
  181. lcnt    dw      0                       ; # of lines in buffer
  182. lmax    dw      ?                       ; max lines of buffer
  183. cbuf    ends
  184.  
  185. twnd    cbuf    <>                      ; top screen spill-buffer struct
  186. bwnd    cbuf    <>                      ; bottom screen spill buffer struct
  187. vtrname db      'TERMINALR'             ; a macro name, must be Upper Case
  188. vtrlen  equ     $-vtrname
  189. vtsname db      'TERMINALS'             ; a macro name, must be Upper Case
  190. vtslen  equ     $-vtsname
  191.  
  192. vtmacname dw    vtrname                 ; pointer to selected macro name
  193. vtmaclen db     vtrlen
  194. datas   ends
  195.  
  196. code    segment public 'code'
  197.         extrn   beep:near, prtchr:near, outchr:near, sbrk:near, pcwait:near
  198.         extrn   isfile:near, strlen:near, strcpy:near   ; in mssfil
  199.         extrn   anstty:near,ansini:near,ansrei:near     ; in mszibm
  200.         extrn   anstat:near,anskbi:near,ansdsl:near     ; in mszibm
  201.         extrn   ans52t:near, vsinit:near                ; in mszibm
  202.         extrn   msuinit:near, keybd:near                ; in msuibm
  203.         extrn   tekini:near,tekcls:near,tekemu:near,tekend:near ;in msgibm
  204.         extrn   tekrint:near
  205.         assume  cs:code, ds:datas, es:datas
  206.  
  207. ; do initialization local to this module
  208. ; Dynamically allocates 4000 bytes for screen save/restore buffer plus
  209. ;  320 to 38400 bytes for screen scroll back buffers. Tries to leave space
  210. ;  for Command.com before enlarging buffers. [jrd]
  211. lclyini proc    near
  212.         call    msuinit                 ; initialize keyboard module msuxxx
  213.  
  214.         mov     ax,swidth*(slen+1)*2    ; (80 char + 80 attr) * 25 lines
  215.         call    sbrk                    ; memory allocation routine (mssker)
  216.                                         ;if we get here them we have the lines
  217.         mov     scrsav,ax               ; memory segment for save screens
  218.                                         ; screen roll back buffers
  219.         mov     bx,0ffffh               ; ask for all of memory, to get size
  220.         mov     ah,alloc                ; allocate all of memory (must fail)
  221.         int     dos                     ; bx has # free paragraphs
  222.         mov     ax,bx                   ; ax has copy of number free paragraphs
  223.         sub     ax,24000D/16            ; space for Command.com copy #2
  224.         jbe     lclyin1                 ; be = not enough for it. [ebb]
  225.         cmp     ax,(swidth*slen+15)/16  ; minimum roll back space left over?
  226.         jbe     lclyin1                 ; be = not even that much
  227.         cmp     ax,(swidth*slen*npages+7)/8 ; paragraphs wanted for roll back
  228.         jbe     lclyin2                 ; be = enough but not more than needed
  229.         mov     ax,(swidth*slen*npages+7)/8 ; limit to our actual needs
  230.         jmp     short lclyin2           ; ask for all we really want
  231. lclyin1:mov     ax,(4*swidth+15)/16     ; use minimum needed paragraphs
  232. lclyin2:mov     inipara,ax              ; save for later resizing of buffers
  233.         mov     cl,4                    ; convert paragraphs to bytes
  234.         shl     ax,cl                   ;  for sbrk
  235.         call    sbrk                    ; ask for that many bytes
  236.                                         ;if we get here them we have the space
  237.         mov     bwnd.orig,ax            ; memory segment, bottom window area
  238.         mov     twnd.orig,ax            ; top. same place for both buffers!
  239.  
  240.         call    scrseg                  ; test running in an Environment
  241.         call    scrmod                  ; read video state, get crt_mode
  242.         mov     ax,low_rgt              ; lower right corner of screen
  243.         mov     al,crt_mode
  244.         mov     crt_norm,al             ; save as normal mode
  245.         mov     savflg,ax
  246.         mov     ah,conout               ; output a space to set background
  247.         mov     dl,' '                  ; and foreground screen colors
  248.         int     dos
  249.         mov     ah,3                    ; get current cursor position into dx
  250.         mov     bh,0
  251.         int     screen
  252.         dec     dl                      ; backup to the space
  253.         mov     ah,2                    ; set cursor
  254.         int     screen
  255.         mov     ah,8                    ; read current attributes
  256.         xor     bh,bh                   ; page 0
  257.         int     screen
  258.         mov     scbattr,ah              ; save video attributes
  259.         mov     oldattr,ah              ; and here too
  260.         mov     ax,inipara              ; # paragraphs allocated by DOS
  261.         mov     cl,3                    ; 2**3 = 8
  262.         shl     ax,cl                   ; paragraphs to words (char + attrib)
  263.         xor     dx,dx                   ; clear extended size
  264.         mov     ch,0
  265.         mov     cl,byte ptr low_rgt
  266.         inc     cl                      ; number of chars per line in buffer
  267.         div     cx                      ; ax = number of lines in buffer
  268.         mov     bwnd.lmax,ax            ; max lines per buffer (quotient)
  269.         mov     twnd.lmax,ax            ; max lines per buffer
  270.         add     cx,cx                   ; count char and attribute per item
  271.         xor     dx,dx                   ; clear extended numerator
  272.         mul     cx                      ; ax = effective # bytes per buffer
  273.         dec     ax                      ; adjust for counting from zero
  274.         mov     bwnd.bend,ax            ; offset of last byte in buffer
  275.         mov     twnd.bend,ax            ; offset of last byte in buffer
  276.         mov     bwnd.pp,0               ; offset of first byte in buffer
  277.         mov     twnd.pp,0               ; offset of first byte in buffer
  278.         mov     bwnd.lcnt,0             ; number of lines occupied in buffer
  279.         mov     twnd.lcnt,0             ; number of lines occupied in buffer
  280.         call    vsinit                  ; init terminal emulator module MSZ
  281.         mov     ega_mode,0              ; assume no EGA
  282.         mov     ax,1200H                ; EGA: Bios alternate select
  283.         mov     bl,10H                  ; Ask for EGA info
  284.         mov     bh,0ffH                 ; Bad info, for testing
  285.         mov     cl,0fH                  ; Reserved switch settings
  286.         int     screen                  ; EGA, are you there?
  287.         cmp     cl,0cH                  ; Test reserved switch settings
  288.         jge     lclyin3                 ; ge = no EGA in use
  289.         push    es
  290.         mov     ax,40h                  ; check Bios 40:87h for ega being
  291.         mov     es,ax                   ;  the active display adapter
  292.         test    byte ptr es:[87h],8     ; is ega active?
  293.         pop     es
  294.         jnz     lclyin3                 ; nz = no
  295.         mov     ega_mode,1              ; yes, set flag to say so
  296.         mov     crt_norm,3              ; assume color monitor is attached
  297.         cmp     bh,0                    ; is color mode in effect?
  298.         je      lclyin3                 ; e = yes
  299.         mov     crt_norm,7              ; else use mode 7 for mono
  300. lclyin3:ret
  301. lclyini endp
  302.  
  303. scrini  proc    near                    ; init screen stuff
  304.         call    scrseg                  ; update screen segment tv_seg(s/o)
  305.         call    scrmod                  ; get screen mode, low_rgt
  306.         mov     ah,3                    ; get cursor position and type
  307.         xor     bh,bh                   ; page 0
  308.         int     screen
  309.         mov     lincur,cx               ; save cursor type (scan line #'s)
  310.         mov     ax,low_rgt              ; present screen text size
  311.         cmp     ax,savflg               ;  vs size of saved screen
  312.         jne     scrin1                  ; ne = different, initialize
  313.         jmp     scrin3                  ; same, skip initialization
  314.                                         ; Re-initialize screen buffers
  315. scrin1: mov     ax,inipara              ; paragraphs allotted to roll back
  316.         mov     cl,3                    ; 2**3 = 8
  317.         shl     ax,cl                   ; paragraphs to words (char + attrib)
  318.         xor     dx,dx                   ; clear extended size
  319.         mov     cl,byte ptr low_rgt     ; number of chars per line in buffer
  320.         inc     cl                      ; chars per line
  321.         xor     ch,ch                   ; clear high byte
  322.         div     cx                      ; ax = number of lines in buffer
  323.         mov     bwnd.lmax,ax            ; max lines per buffer (quotient)
  324.         mov     twnd.lmax,ax            ; max lines per buffer
  325.         add     cx,cx                   ; count char and attribute per item
  326.         xor     dx,dx                   ; clear extended numerator
  327.         mul     cx                      ; ax = effective # bytes per buffer
  328.         dec     ax                      ; adjust for counting from zero
  329.         mov     bwnd.bend,ax            ; offset of last byte in buffer
  330.         mov     twnd.bend,ax            ; offset of last byte in buffer
  331.         mov     bwnd.pp,0               ; offset of first byte in buffer
  332.         mov     twnd.pp,0               ; offset of first byte in buffer
  333.         mov     bwnd.lcnt,0             ; number of lines occupied in buffer
  334.         mov     twnd.lcnt,0             ; number of lines occupied in buffer
  335.  
  336.         mov     ega_mode,0              ; assume no EGA
  337.         mov     ax,1200H                ; EGA: Bios alternate select
  338.         mov     bl,10H                  ; Ask for EGA info
  339.         mov     bh,0ffH                 ; Bad info, for testing
  340.         mov     cl,0fH                  ; Reserved switch settings
  341.         int     screen                  ; EGA, are you there?
  342.         cmp     cl,0cH                  ; Test reserved switch settings
  343.         jge     scrin2                  ; ge = no EGA in use
  344.         push    es
  345.         mov     ax,40h                  ; check Bios 40:87h for ega being
  346.         mov     es,ax                   ;  the active display adapter
  347.         test    byte ptr es:[87h],8     ; is ega active?
  348.         pop     es
  349.         jnz     scrin2                  ; nz = no
  350.         mov     ega_mode,1              ; yes, set flag to say so
  351.         mov     crt_norm,3              ; assume color monitor is attached
  352.         cmp     bh,0                    ; is color mode in effect?
  353.         je      scrin2                  ; e = yes
  354.         mov     crt_norm,7              ; else use mode 7 for mono
  355. scrin2: mov     ah,oldattr              ; get init time attributes
  356.         mov     curattr,ah              ; and set nice screen attribute
  357.         mov     scbattr,ah
  358.         mov     cursor,0                ; cursor to upper left corner
  359.         cmp     flags.vtflg,0           ; terminal type of None?
  360.         ja      scrin3                  ; a = no, emulating
  361.         mov     dh,byte ptr low_rgt+1
  362.         inc     dh                      ; bottom
  363.         mov     dl,0                    ;  left corner
  364.         jmp     short scrin5
  365.                                         ; Common finish code
  366. scrin3: mov     dx,cursor               ; use old cursor, if any
  367.         cmp     flags.vtflg,0           ; emulating?
  368.         je      scrin4                  ; e = no
  369.         cmp     dh,byte ptr low_rgt+1   ; past logical end of screen?
  370.         jbe     scrin4                  ; be = no, keep going
  371.         mov     dh,byte ptr low_rgt+1   ; yes, just use lower right corner
  372. scrin4: cmp     dl,byte ptr low_rgt     ; maybe past right margin
  373.         jbe     scrin5                  ; be = no, use the way it is
  374.         mov     dl,byte ptr low_rgt
  375. scrin5: mov     cursor,dx               ; init cursor
  376.         mov     ah,2                    ; set cursor position
  377.         xor     bh,bh                   ; page zero
  378.         int     screen                  ; set cursor in case it moved
  379.         test    flags1,inited           ; have we run yet?
  380.         jz      scrin7                  ; z = no, so no saved screen yet
  381.         call    restscr                 ; restore screen
  382. scrin7: or      flags1,inited           ; remember we've run already
  383.         cmp     flags.modflg,1          ; is mode line on and locally owned?
  384.         ja      scrin10                 ; a = host owned, leave intact
  385.         cmp     flags.vtflg,0           ; emulating a terminal?
  386.         jne     scrin8                  ; ne = yes, can have mode line
  387.         or      yflags,modoff           ; for no emulation say toggled off
  388.         cmp     trmtyp,0                ; previous terminal type = none?
  389.         jne     scrin9                  ; ne = no. need to clear mode line
  390.         jmp     scrin10                 ; yes, let 25th line be intact
  391. scrin8: cmp     flags.modflg,0          ; is mode line disabled?
  392.         je      scrin9                  ; e = yes, clear it
  393.         test    yflags,modoff           ; is mode line toggled off?
  394.         jnz     scrin9                  ; nz = yes, clear the line
  395.         call    modlin                  ; turn on mode line
  396.         jmp     short scrin10
  397. scrin9: call    clrmod                  ; ensure its off
  398. scrin10:cmp     flags.vtflg,0           ; current terminal type = None?
  399.         je      scrin12                 ; e = yes, nothing to init
  400.         mov     al,yflags               ; tell emulator we are back
  401.         cmp     vtclear,0               ; screen need clearing?
  402.         jne     scrin10a                ; yes, do emulator reinit now
  403.         cmp     vtinited,inited         ; inited emulator yet?
  404.         je      scrin11                 ; e = yes
  405.         cmp     tekflg,0                ; Tek mode still active?
  406.         jne     scrin12                 ; ne = yes, no re-init here
  407. scrin10a:call   vtinit                  ; init it now
  408.         mov     vtclear,0               ; say screen is clear
  409.         jmp     short scrin12
  410. scrin11:call    ansrei                  ; reinit the emulator
  411.         call    ansflg                  ; and get its flags
  412. scrin12:mov     al,flags.vtflg          ; current terminal type
  413.         mov     trmtyp,al               ; place to remember it til next time
  414.         cmp     flags.vtflg,tttek       ; Tek mode?
  415.         je      scrin13                 ; e = yes
  416.         cmp     tekflg,0                ; Tek mode active within DEC stuff?
  417.         je      scrin14                 ; e = no
  418. scrin13:call    tekini                  ; reinit to get graphics screen
  419. scrin14:ret
  420. scrini  endp
  421.  
  422. ; Routine to initialize VT102/52/Heath-19 terminal emulator.
  423.  
  424. vtinit  proc    near
  425.         mov     holdscr,0               ; clear holdscreen
  426.         cmp     flags.vtflg,0           ; doing emulation?
  427.         je      vtinix                  ; e = no
  428.         cmp     tekflg,0                ; Tek mode active?
  429.         jne     vtini2                  ; ne = yes, do it's reinit
  430.         or      vtinited,inited
  431.         call    ansflg                  ; update ansi flags
  432.         mov     bx,argadr               ; Get address of argument block
  433.         mov     dl,[bx].flgs
  434.         and     dl,lclecho
  435.         and     yflags,not lclecho
  436.         or      yflags,dl
  437.         mov     al,yflags               ; Pass the flags
  438.         mov     dl,[bx].baudb           ; Baud rate code in dl
  439.         mov     dh,[bx].parity          ; Parity code in bits
  440.         mov     cl,4                    ; 0-3 of dh
  441.         shl     dh,cl
  442.         or      dh,07H                  ; Just say 7 data bits
  443.         test    flags.remflg,d8bit      ; eight bit display?
  444.         jz      vtini1                  ; z = no
  445.         inc     dh                      ; set low four bits to value 8
  446. vtini1: call    ansini                  ; call startup routine in mszibm
  447. vtinix: clc
  448.         ret
  449. vtini2: call    tekrint                 ; reinitialize Tek emulator
  450.         clc
  451.         ret
  452. vtinit  endp
  453.  
  454.  
  455. argini  proc    near                    ; read passed arguments
  456.         mov     bx,argadr               ; base of argument block
  457.         mov     al,[bx].flgs            ; get flags
  458.         and     al,capt+emheath+havtt+trnctl+lclecho+modoff+lnwrap
  459.         mov     yflags,al               ; mask for allowable and save
  460.         mov     al,[bx].prt
  461.         mov     portno,al               ; update port number
  462.         mov     al,[bx].rows
  463.         mov     crt_lins,al             ; init # of rows and cols
  464.         mov     ax,[bx].captr
  465.         mov     captrtn,ax              ; buffer capture routine
  466.         mov     al,[bx].escc
  467.         mov     esc_ch,al
  468.         mov     parmsk,0ffh             ; parity mask, assume parity = None
  469.         cmp     [bx].parity,parnon      ; is parity None?
  470.         je      argini1                 ; e = yes, keep all 8 bits
  471.         mov     parmsk,07fh             ; else keep lower 7 bits
  472. argini1:ret                             ; that's it
  473. argini  endp
  474.  
  475. modlin  proc    near                    ; turn on mode line
  476.         mov     al,esc_ch
  477.         mov     modbuf.m_echr,' '       ; first char is initial space
  478.         mov     modbuf.m_hlp,' '        ; goes here too
  479.         cmp     al,32                   ; printable?
  480.         jnb     modl1                   ; yes, keep going
  481.         add     al,40h                  ; made printable
  482.         mov     modbuf.m_echr,5eh       ; caret, note control char
  483.         mov     modbuf.m_hlp,5eh
  484. modl1:  mov     modbuf.m_echr+1,al      ; fill in character
  485.         mov     modbuf.m_hlp+1,al
  486.         mov     bx,argadr               ; get argument block
  487.         mov     al,[bx].baudb           ; get baud bits
  488.         mov     si,offset unkbaud       ; assume unknown baud
  489.         cmp     al,baudnsiz             ; too big?
  490.         jnb     modl2                   ; nb = yes, use default
  491.         mov     cl,size m_baud          ; each is 5 bytes long
  492.         mul     cl
  493.         mov     ah,0
  494.         add     ax,offset baudn
  495.         mov     si,ax
  496. modl2:  mov     cx,size m_baud          ; length of baud space
  497.         mov     di,offset modbuf.m_baud
  498.         push    es                      ; save es
  499.         push    ds
  500.         pop     es                      ; set es to datas segment
  501.         cld
  502.         rep     movsb                   ; copy in baud rate
  503.         mov     al,[bx].parity          ; get parity code
  504.         shl     al,1                    ; each is 4 bytes long
  505.         shl     al,1
  506.         mov     ah,0
  507.         add     ax,offset parnams       ; names of parity settings
  508.         mov     si,ax
  509.         mov     cx,4                    ; each is 4 long
  510.         mov     di,offset modbuf.m_par
  511.         rep     movsb
  512.         mov     si,offset remmsg        ; Assume remote echoing
  513.         test    yflags,lclecho          ; Is remote side echoing?
  514.         jz      modl4                   ; Yes, keep going
  515.         mov     si,offset lclmsg        ; Else it's local echoing.
  516. modl4:  mov     cx,3                    ; size of on/off
  517.         mov     di,offset modbuf.m_echo
  518.         rep     movsb
  519.         mov     al,portno               ; communications port
  520.         cmp     al,' '                  ; binary (non-printable)?
  521.         jae     modl5                   ; ae = no, ascii
  522.         add     al,'0'                  ; convert to ascii
  523. modl5:  mov     modbuf.m_prt,al         ; fill in port number
  524.         mov     cx,8                    ; blank out terminal id field
  525.         mov     si,offset mtty          ; assume no terminal emulation
  526.         mov     di,offset modbuf.m_term ; destination
  527.         rep     movsb                   ; copy it in
  528.         mov     modbuf.m_prn,' '        ; assume not printing the screen
  529.         mov     modbuf.m_prn+1,' '
  530.         mov     modbuf.m_prn+2,' '
  531.         test    anspflg,prtscr          ; doing a print the screen?
  532.         jz      modl5a                  ; z = no
  533.         mov     modbuf.m_prn,'P'        ; yes. display PRN at end of line
  534.         mov     modbuf.m_prn+1,'R'
  535.         mov     modbuf.m_prn+2,'N'
  536. modl5a: mov     cx,size modfrm          ; this is size of mode line
  537.         mov     si,offset modbuf        ; mode line image
  538.         pop     es
  539.                         ; alternate entry to write an alternate mode line
  540. modwrt: push    cx
  541.         push    si                      ; save mode line and size
  542.         mov     ah,3                    ; read cursor position
  543.         xor     bx,bx                   ; screen page 0
  544.         int     screen
  545.         mov     cursor,dx               ; save cursor position
  546.         call    trmatt                  ; Get terminal attributes
  547.         and     ah,77h                  ; omit blinking/bold attributes
  548.         mov     bh,ah                   ; get video attribute
  549.         mov     dx,low_rgt              ; right most column
  550.         inc     dh                      ; refer to status line
  551.         mov     ch,dh                   ; bottom line [dlk]
  552.         mov     cl,0                    ; left col = 0 (first) [dlk]
  553.         mov     ax,600h                 ; scroll to clear the line
  554.         int     screen
  555.         mov     dh,byte ptr low_rgt+1   ; refer to status line
  556.         inc     dh
  557.         xor     dl,dl                   ; left most column
  558.         mov     bh,0
  559.         mov     ah,2                    ; set cursor position
  560.         int     screen
  561.         pop     si
  562.         pop     cx                      ; restore these
  563.         cmp     cl,crt_cols             ; mode line longer than screen?
  564.         jbe     modl6                   ; le = no
  565.         mov     cl,crt_cols             ; else do just one line's worth
  566.         dec     cx                      ; don't let screen scroll
  567. modl6:  cld
  568.         lodsb                           ; get a byte
  569.         mov     ah,14                   ; write to terminal
  570.         mov     bh,0                    ; page 0
  571.         int     screen
  572.         loop    modl6                   ; write out entire mode line
  573.         cmp     flags.vtflg,0           ; emulating?
  574.         je      modl7                   ; e = no
  575.         and     yflags,not modoff       ; update local flags (mode line on)
  576.         mov     al,yflags               ; Yes - update flags also
  577.         call    ansdsl                  ; get extras from emulator
  578. modl7:  mov     dx,cursor
  579.         mov     ah,2
  580.         mov     bh,0
  581.         int     screen                  ; put cursor back where it belongs
  582.         ret
  583. modlin  endp
  584.  
  585. clrmod  proc    near                    ; clear mode line
  586.         call    trmatt                  ; Get terminal screen attributes
  587.         mov     bh,al                   ; Use screen background attribute
  588.         mov     ax,600h                 ; blank window
  589.         mov     dx,low_rgt              ; right most column
  590.         inc     dh                      ; refer to status line
  591.         mov     cx,dx                   ; bottom line [dlk]
  592.         xor     cl,cl                   ; left most column
  593.         int     screen                  ; clear mode line
  594.         or      yflags,modoff           ; turn on flag
  595.         ret
  596. clrmod  endp
  597.  
  598.  
  599. ; Fetch screen attributes from emulator (if emulating). It exists mainly
  600. ; so that the reverse video will work.   Returns the current mode
  601. ; line background attribute in ah, the current screen background in al,
  602. ; and the current "cursor" (foreground) attribute in bl.  (Note: anstat
  603. ; returns status yflags in bh).
  604.  
  605. trmatt  proc    near                    ; Get attributes
  606.         cmp     flags.vtflg,0           ; emulating?
  607.         je      trmat1                  ; No, just do simple stuff
  608.         mov     al,yflags               ; anstat expects flags byte in al
  609.         call    anstat                  ; Fetch emulator status/attributes
  610.         ret
  611. trmat1: mov     al,scbattr              ; Background attributes
  612.         mov     bl,curattr              ; And cursor attribute
  613.         mov     ah,al                   ; where modlin needs them
  614.         and     ah,77h                  ; get colors part, no blink/bold
  615.         rol     ah,1                    ; reverse them
  616.         rol     ah,1
  617.         rol     ah,1
  618.         rol     ah,1
  619.         ret
  620. trmatt  endp
  621.  
  622. ; Get byte yflags of terminal emulator passed in AL. Used in mode line
  623. ; handling when 25th line is used by the emulator. [jrd]
  624. telmsy  proc    near
  625.         mov     yflags,al               ; get the updated flags
  626.         call    ansflg                  ; and any other emulator info
  627.         ret
  628. telmsy  endp
  629.  
  630.  
  631. ;[IU2] This routine updates the ANSI status flags from the emulator,
  632. ; and passes the "yflags" byte to the VT100 emulator also.
  633.  
  634. ansflg  proc    near
  635.         push    ax                      ; save regs
  636.         push    bx
  637.         mov     al,yflags
  638.         call    anstat                  ; Get status and attributes
  639.         mov     ansflgs,bh              ; Save
  640.         test    ansflgs,dececho         ; does host want us to do local echo?
  641.         jz      ansflg1                 ; z = no, use working default
  642.         or      yflags,lclecho          ; turn on local echoing
  643. ansflg1:pop     bx
  644.         pop     ax
  645.         ret
  646. ansflg  endp
  647.  
  648. getflgs proc    near                    ; supply yflags for terminal emulators
  649.         mov     al,yflags
  650.         ret
  651. getflgs endp
  652.  
  653. term    proc    near                    ; terminal mode entry point
  654.         mov     argadr,ax               ; save argument ptr
  655.         call    argini                  ; init options from arg address
  656.         call    scrini                  ; init screen stuff
  657.         mov     bx,portval              ; port data structure address
  658.         mov     bx,[bx].flowc           ; get flow control chars (bl=xoff)
  659.         mov     flowon,bh
  660.         mov     flowoff,bl              ; save for later
  661.         mov     oldsp,sp                ; remember stack for i/o failure,
  662.                                         ;  used by procedure  endcon
  663. lp:     call    prtchr                  ; char at port?
  664.          jmp    short lpinp             ; yes, go handle
  665.          nop                            ; else look at kbd
  666. lpkbd:  mov     fairness,0              ; say kbd was examined
  667.         call    keybd                   ; call keyboard translator in msu
  668.         jnc     lp                      ; nc = no char or have processed it
  669.         jmp     short quit              ; carry set = quit connect mode
  670. lpinp:  and     al,parmsk               ; apply 8/7 bit parity mask
  671.         call    outtty                  ; print on terminal
  672.         inc     fairness                ; say read port but not kbd, again
  673.         cmp     fairness,100            ; this many port reads before kbd?
  674.         jb      lp                      ; b = no, read port again
  675.         jmp     short lpkbd             ; yes, let user have a chance too
  676.  
  677. quit:   call    pntflsh                 ; flush printer buffer
  678.         call    tekend                  ; cleanup Tektronix mode [bjh]
  679.         mov     ah,3                    ; get cursor position into dx
  680.         xor     bh,bh                   ; page 0
  681.         int     screen
  682.         mov     cursor,dx               ; save position
  683.         cmp     flags.vtflg,0           ; terminal type of none?
  684.         ja      quit1                   ; a = yes
  685.         test    yflags,modoff           ; is modeline still toggled off?
  686.         jnz     quit1                   ; nz = yes
  687.         call    clrmod                  ; clear it before storing screen
  688. quit1:  call    savescr                 ; save screen
  689.         mov     ax,0600h                ; clear mode line with old attributes
  690.         mov     bh,oldattr              ; attributes
  691.         mov     dx,low_rgt              ; right most column
  692.         inc     dh                      ; refer to status line
  693.         mov     cx,dx                   ; bottom line [dlk]
  694.         xor     cl,cl                   ; left most column
  695.         int     screen                  ; clear the mode line
  696.         mov     ah,oldattr              ; attributes at init time
  697.         mov     scbattr,ah              ; background = original state
  698.                                         ; for ega in non-standard # lines
  699.         cmp     ega_mode,0              ; ega board active?
  700.         je      quit2                   ; e = no
  701.         cmp     byte ptr low_rgt+1,23   ; is screen standard length?
  702.         je      quit2                   ; e = yes, so regular cursor set is ok
  703.         push    es                      ; turn off ega cursor emulation
  704.         mov     ax,40h                  ; byte 40:87H is ega Info byte
  705.         mov     es,ax
  706.         push    es:[87h]                ; save info byte around call
  707.         or      byte ptr es:[87h],1     ; set emulation off (low bit = 1)
  708.         mov     cx,lincur               ; cursor shape to set
  709.         mov     ah,1                    ; set the shape
  710.         int     screen                  ;   back to starting value
  711.         pop     es:[87h]                ; recover original Info byte
  712.         pop     es                      ; and our work reg
  713.         jmp     short quit3             ; skip regular mode cursor setting
  714. quit2:                                  ; for regular sized screen
  715.         mov     cx,lincur               ; cursor type at startup
  716.         mov     ah,1
  717.         int     screen                  ; restore cursor type
  718. quit3:  mov     ah,2                    ; Position cursor
  719.         mov     bh,0                    ; Page 0
  720.         mov     dx,low_rgt              ; bottom line
  721.         inc     dh                      ; status line position
  722.         xor     dl,dl                   ; left most column
  723.         int     screen                  ; Do it
  724.         mov     al,yflags
  725.         and     al,not lclecho          ; don't copy host's echo flag
  726.         mov     bx,argadr
  727.         mov     ah,[bx].flgs            ; get user's flag settings
  728.         and     ah,lclecho              ; clear all but local echo bit
  729.         or      [bx].flgs,al            ; update flags in arg block
  730.         ret
  731. term    endp
  732.  
  733. ; put the character in al to the screen
  734. outtty  proc    near
  735.         cmp     flags.vtflg,0           ; emulating a terminal?
  736.         jne     outnoc                  ; ne = yes, emulator handles printing
  737.         test    flags.remflg,d8bit      ; keep 8 bits for displays?
  738.         jnz     outnp9                  ; nz = yes, 8 bits if possible
  739.         and     al,7fh                  ; remove high bit
  740. outnp9: cmp     rxtable+256,0           ; translation turned off?
  741.         je      outnp7                  ; e = yes, no translation
  742.         push    bx
  743.         mov     bx,offset rxtable       ; address of translate table
  744.         xlatb                           ; new char is in al
  745.         pop     bx
  746. outnp7: test    anspflg,prtscr          ; should we be printing?
  747.         jz      outnop                  ; no, keep going
  748.         call    pntchr                  ; queue char for printer
  749.         jnc     outnop                  ; nc = successful print
  750.         push    ax
  751.         call    beep                    ; else make a noise and
  752.         call    trnprs                  ;  turn off printing
  753.         pop     ax
  754. outnop: test    yflags,capt             ; capturing output?
  755.         jz      outnoc                  ; no, forget this part
  756.         push    ax                      ; save char
  757.         call    captrtn                 ; give it captured character
  758.         pop     ax                      ; restore character and keep going
  759. outnoc: cmp     vtroll,0                ; auto roll back allowed?
  760.         jz      outnp6                  ; z = no, leave screen as is
  761.         cmp     tekflg,0                ; Tek mode active?
  762.         jne     outnp6                  ; ne = yes, skip screen rolling
  763.         cmp     bwnd.lcnt,0             ; is screen rolled back? [dlk]
  764.         je      outnp6                  ; e = no
  765.         call    endwnd                  ; restore screen before writing [dlk]
  766. outnp6: cmp     flags.vtflg,0           ; emulating a terminal?
  767.         jne     outnop1                 ; ne = yup, go do something smart
  768.         test    yflags,trnctl           ; debug? if so use Bios tty mode
  769.         jz      outnp4                  ; z = no
  770.         mov     ah,biostty              ; Bios tty screen write
  771.         cmp     al,7fh                  ; Ascii Del char or greater?
  772.         jb      outnp1                  ; b = no
  773.         je      outnp0                  ; e = Del char
  774.         push    ax                      ; save the char
  775.         mov     al,7eh                  ; output a tilde for 8th bit
  776.         int     screen
  777.         pop     ax                      ; restore char
  778.         and     al,7fh                  ; strip high bit
  779. outnp0: cmp     al,7fh                  ; is char now a DEL?
  780.         jne     outnp1                  ; ne = no
  781.         and     al,3fH                  ; strip next highest bit (Del --> '?')
  782.         jmp     outnp2                  ; send, preceded by caret
  783. outnp1: cmp     al,' '                  ; control char?
  784.         jae     outnp3                  ; ae = no
  785.         add     al,'A'-1                ; make visible
  786. outnp2: push    ax                      ; save char
  787.         mov     al,5eh                  ; caret
  788.         int     screen                  ; display it
  789.         pop     ax                      ; recover the non-printable char
  790. outnp3: push    ax
  791.         int     screen
  792.         pop     ax
  793.         ret
  794. outnp4: cmp     al,bell                 ; bell (Control G)?
  795.         jne     outnp5                  ; ne = no
  796.         jmp     beep                    ; use short beep, avoid char loss
  797. outnp5: mov     dl,al                   ; write without intervention
  798.         mov     ah,conout
  799.         int     dos                     ; else let dos display char
  800.         ret
  801.  
  802. outnop1:cmp     flags.vtflg,tttek       ; doing Tektronix emulation?
  803.         je      outnop2                 ; e = yes, use Tek emulator
  804.         cmp     tekflg,0                ; Tek submode active?
  805.         jne     outnop2                 ; ne = yes, use Tek emulator
  806.         jmp     anstty                  ; call terminal emulator routine & ret
  807. outnop2:jmp     tekemu                  ; use Tek emulator and return
  808.  
  809. outtty  endp
  810.  
  811. ;[IU2] Here to output character to port with no echo (like escape sequences
  812. ; sent by PF keys, responses to requests from the host, etc.   It is
  813. ; wrong thinking to echo these).
  814.  
  815. prtbout proc    near                    ; Global routine now
  816.         mov     ah,al                   ; This is where outchr expects it
  817.         call    outchr
  818.          jmp    endcon                  ; failure, end connection
  819.          nop
  820.         clc                             ; carry clear for success
  821.         ret
  822. prtbout endp
  823.  
  824.  
  825. ;[IU2] Here to output an unsigned 8-bit number (in al) to the port without
  826. ; echoing. Used by terminal emulator escape sequence output.
  827.  
  828. prtnout proc    near
  829.         mov     bl,10                   ; Output in base 10
  830.         jmp     prtno2                  ; Ensure at least a zero
  831.  
  832. prtno1: cmp     al,0
  833.         jne     prtno2                  ; Yes - do more digits
  834.         ret                             ; No - return from recursive call
  835. prtno2: mov     ah,0                    ; Clear previous remainder
  836.         div     bl                      ; Divide off a digit
  837.         push    ax                      ; Push remainder (in ah) on stack
  838.         call    prtno1                  ; Recur
  839.         pop     ax                      ; Pop off a digit
  840.         add     ah,'0'                  ; Make it ASCII
  841.         call    outchr                  ; send to port
  842.          jmp    endcon                  ; failure, end connection
  843.          nop
  844.         clc                             ; carry clear for success
  845.         ret
  846. prtnout endp
  847.  
  848. ; send the character in al out to the serial port; handle echoing.
  849. ; Can send an 8 bit char while displaying only 7 bits locally.
  850. outprt  proc    near
  851.         test    yflags,lclecho          ; echoing?
  852.         jz      outpr1                  ; z = no, forget it
  853.         push    ax                      ; save char
  854.         call    outtty                  ; print it
  855.         pop     ax                      ; restore
  856. outpr1: mov     ah,al                   ; this is where outchr expects it
  857.         call    outchr                  ; output to the port
  858.          jmp    endcon                  ; failure, end connection
  859.          nop
  860.         clc                             ; carry clear for success
  861.         ret
  862. outprt  endp
  863.  
  864. ; Jump here to exit Connect mode and execute macros 'TERMINALR' (vtrmac) or
  865. ; 'TERMINALS' (vtsmac). Does nothing if macro does not exist.
  866. ; Preserves registers except ax. Returns to TELNET caller with 'C' in kbdflg.
  867. vtrmac  proc    near                    ; RESET macro
  868.         mov     ax,offset vtrname       ; select macro name
  869.         mov     vtmacname,ax
  870.         mov     vtmaclen,vtrlen         ; and its length
  871.         jmp     short vtmacro           ; finish in common code
  872. vtrmac  endp
  873.  
  874. vtsmac  proc    near                    ; SET macro
  875.         mov     ax,offset vtsname
  876.         mov     vtmacname,ax
  877.         mov     vtmaclen,vtslen
  878.         jmp     short vtmacro
  879. vtsmac  endp
  880.  
  881. ;
  882. ; Reference     Macro structure for     db      number of entries (mac names)
  883. ;  is file       table mcctab      |->  db      length of macroname, excl '$'
  884. ;  mssset.asm           each entry |->  db      'macroname','$'
  885. ;  where these                     |->  dw      offset of definition string
  886. ;  are stored.
  887. ;               Definition string in    db      length of <string with null>
  888. ;                buffer macbuf          db      'string with trailing null'
  889. ;
  890. vtmacro proc    near                    ; common code for macros vtsmac,vtrmac
  891.         push    bx
  892.         push    cx
  893.         push    si
  894.         mov     bx,offset mcctab        ; table of macro names
  895.         mov     cl,[bx]                 ; number of names in table
  896.         xor     ch,ch
  897.         jcxz    vtmacx                  ; z = empty table, do nothing
  898.         inc     bx                      ; point to length of first name
  899. vtmac2: mov     al,[bx]                 ; length of this name
  900.         xor     ah,ah
  901.         cmp     al,vtmaclen             ; length same as desired keyword?
  902.         jne     vtmac3                  ; ne = no, search again
  903.         mov     si,bx
  904.         inc     si                      ; point at first char of name
  905.         push    cx                      ; save name counter
  906.         push    di                      ; save reg
  907.         mov     cl,vtmaclen             ; length of name, excluding '$'
  908.         xor     ch,ch
  909.         mov     di,vtmacname            ; point at desired macro name
  910.         push    es                      ; save reg
  911.         push    ds
  912.         pop     es                      ; make es use datas segment
  913.         cld
  914.         repe    cmpsb                   ; match strings
  915.         pop     es                      ; need current si below
  916.         pop     cx
  917.         pop     di                      ; recover saved regs
  918.         je      vtmac4                  ; e = matched
  919. vtmac3: add     bx,ax                   ; step to next name, add name length
  920.         add     bx,4                    ; + count, dollar sign, def word ptr
  921.         loop    vtmac2                  ; try next name
  922. vtmacx: pop     si                      ; no macro, return to Connect mode
  923.         pop     cx
  924.         pop     bx
  925.         ret
  926.  
  927. vtmac4: cmp     taklev,maxtak           ; room in Take level?
  928.         jge     vtmacx                  ; ge = no, exit with no action
  929.         inc     taklev                  ; increment take level
  930.         add     takadr,size takinfo     ; make a new Take entry/macro
  931.         mov     bx,takadr               ; point to current macro structure
  932.         inc     si                      ; skip dollar sign after name
  933.         mov     si,[si]                 ; get definition address
  934.         mov     [bx].takbuf,si          ; address of definition string struc
  935.         mov     cl,[si]                 ; length byte of definition
  936.         xor     ch,ch
  937.         mov     [bx].takcnt,cx          ; number of chars in definition
  938.         inc     si                      ; address of definition text proper
  939.         mov     [bx].takptr,si          ; where to read next command char
  940.         mov     [bx].taktyp,0ffh        ; flag as a macro
  941.         pop     si
  942.         pop     cx
  943.         pop     bx
  944.         jmp     endcon                  ; exit Connect mode
  945. vtmacro endp
  946.  
  947. ; Error recovery routine used when outchr reports unable to send character
  948. ;  or when vtmacro requests exiting Connect mode.
  949. ; Exit Connect mode cleanly, despite layers of intermediate calls.
  950. endcon  proc    near
  951.         mov     kbdflg,'C'              ; report 'C' to TERM's caller
  952.         mov     sp,oldsp                ; recover startup stack pointer
  953.                                         ; TERM caller's return address is now
  954.                                         ; on the top of stack. A longjmp.
  955.         jmp     quit                    ; exit Connect mode cleanly
  956. endcon  endp
  957.  
  958. ;;; Action routines (verbs) for keyboard translator KEYBD in msuibm.
  959. ; These are invoked by a jump instruction. Return carry clear for normal
  960. ; processing, return carry set for invoking Quit (kbdflg has transfer char).
  961. uparrw: mov     al,'A'                  ; cursor keys
  962.         jmp     short comarr
  963. dnarrw: mov     al,'B'
  964.         jmp     short comarr
  965. rtarr:  mov     al,'C'
  966.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  967.         jz      comarr                  ; z = yes
  968.         mov     al,'D'                  ; reverse sense of keys
  969.         jmp     short comarr
  970. lfarr:  mov     al,'D'
  971.         test    vtemu.vtflgop,vswdir    ; writing left to right?
  972.         jz      comarr                  ; z = yes
  973.         mov     al,'C'                  ; reverse sense of keys
  974. comarr: push    ax                      ; save final char
  975.         mov     ttyact,0                ; network, group chars for packet
  976.         mov     al,escape               ; Output an escape
  977.         call    outprt                  ; Output, echo permitted
  978.         cmp     flags.vtflg,tttek       ; Tek terminal?
  979.         je      comar0                  ; e = yes, use VT100 codes
  980.         cmp     flags.vtflg,ttvt100     ; VT100 terminal emulation?
  981.         jne     comar2                  ; No, do VT52/HEATH-19 sequence
  982. comar0: call    ansflg                  ; Update flags all around
  983.         mov     al,'['                  ; Maybe this next?
  984.         test    ansflgs,decckm          ; Cursor key mode reset?
  985.         je      comar1                  ; Yes, output the "["
  986.         mov     al,'O'                  ; No, set, use the "O"
  987. comar1: call    outprt                  ; Output it (echo permitted)
  988. comar2: pop     ax                      ; recover final char
  989.         mov     ttyact,1                ; network, restore tty active flag
  990.         call    outprt                  ; Output to port (echo permitted)
  991.         ret
  992.  
  993. pf1:    mov     al,'P'                  ; keypad function keys 1-4
  994.         jmp     short compf
  995. pf2:    mov     al,'Q'
  996.         jmp     short compf
  997. pf3:    mov     al,'R'
  998.         jmp     short compf
  999. pf4:    mov     al,'S'
  1000. compf:  push    ax                      ; save final char
  1001.         mov     ttyact,0                ; network, group chars for packet
  1002.         mov     al,escape               ; Output an escape
  1003.         call    prtbout
  1004.         call    ansflg                  ; get emulator flags
  1005.         test    ansflgs,decanm          ; ansi mode?
  1006.         jz      short compf1            ; z = no
  1007.         mov     al,'O'                  ; send an "O"
  1008.         call    prtbout                 ; Output it
  1009. compf1: pop     ax                      ; Get the saved char back
  1010.         mov     ttyact,1                ; network, restore tty active flag
  1011.         call    prtbout                 ; Output to port
  1012.         ret
  1013.  
  1014. kp0:    mov     al,'p'                  ; keypad numeric keys
  1015.         jmp     short comkp
  1016. kp1:    mov     al,'q'
  1017.         jmp     short comkp
  1018. kp2:    mov     al,'r'
  1019.         jmp     short comkp
  1020. kp3:    mov     al,'s'
  1021.         jmp     short comkp
  1022. kp4:    mov     al,'t'
  1023.         jmp     short comkp
  1024. kp5:    mov     al,'u'
  1025.         jmp     short comkp
  1026. kp6:    mov     al,'v'
  1027.         jmp     short comkp
  1028. kp7:    mov     al,'w'
  1029.         jmp     short comkp
  1030. kp8:    mov     al,'x'
  1031.         jmp     short comkp
  1032. kp9:    mov     al,'y'
  1033.         jmp     short comkp
  1034. kpminus:mov     al,'m'
  1035.         jmp     short comkp
  1036. kpcoma: mov     al,'l'
  1037.         jmp     short comkp
  1038. kpenter:mov     al,'M'
  1039.         jmp     short comkp
  1040. kpdot:  mov     al,'n'
  1041. comkp:  test    ansflgs,deckpam         ; keypad application mode active?
  1042.         jnz     comkp3                  ; nz = yes, use escape sequences
  1043.         sub     al,40h                  ; deduct offset to numeric symbols
  1044.         jmp     comkp0                  ; and send that single char
  1045. comkp3: push    ax                      ; save final char
  1046.         mov     ttyact,0                ; network, group chars for packet
  1047.         mov     al,escape               ; Output an escape
  1048.         call    prtbout
  1049.         mov     al,'O'                  ; Output the "O"
  1050.         cmp     flags.vtflg,ttvt100     ; VT100 mode?
  1051.         je      comkp1                  ; e = yes, use "O" code
  1052.         cmp     flags.vtflg,tttek       ; Tek terminal
  1053.         je      comkp1                  ; e = yes, use VT100 codes
  1054.         test    ansflgs,decanm          ; ANSI (alt application keypad) mode?
  1055.         jnz     comkp1                  ; nz = yes, use "O"
  1056. comkp2: mov     al,'?'                  ; else use "?" instead of "O"
  1057. comkp1: call    prtbout
  1058.         pop     ax                      ; recover final char
  1059. comkp0: mov     ttyact,1                ; network, restore tty active flag
  1060.         call    prtbout                 ; send it
  1061.         ret
  1062.  
  1063. klogon  proc    near                    ; resume logging (if any)
  1064.         test    flags.capflg,logses     ; session logging enabled?
  1065.         jz      klogn                   ; z = no, forget it
  1066.         or      argadr.flgs,capt        ; turn on capture flag
  1067.         or      yflags,capt             ; set local msy flag as well
  1068.         call    ansflg                  ; tell emulator
  1069. klogn:  clc
  1070.         ret
  1071. klogon  endp
  1072.  
  1073. klogof  proc    near                    ; suspend logging (if any)
  1074.         and     argadr.flgs,not capt    ; stop capturing
  1075.         and     yflags,not capt         ; reset local msy flag as well
  1076.         call    ansflg                  ; tell emulator
  1077. klogo:  clc
  1078.         ret
  1079. klogof  endp
  1080.  
  1081. snull   proc    near                    ; send a null byte
  1082.         mov     al,0                    ; the null
  1083.         jmp     prtbout                 ; send without logging and local echo
  1084. snull   endp
  1085.  
  1086. khold:  xor     holdscr,1               ; toggle Hold screen byte for msx
  1087.         clc
  1088.         ret
  1089.                                         ; general character out for emulator
  1090. chrout: cmp     flags.vtflg,0           ; emulating?
  1091.         je      chrou5                  ; e = no
  1092.         call    anskbi                  ; Yes, say we had keyboard input
  1093.         cmp     al,cr                   ; A CR?
  1094.         jne     chrou5                  ; No - just output it and return
  1095.         call    ansflg                  ; Yes - update VT100 flags
  1096.         test    ansflgs,anslnm          ; ANSI new-line mode set?
  1097.         jz      chrou5                  ; No - just send the cr
  1098.         call    outprt                  ; Yes - output a carriage-return
  1099.         mov     al,lf                   ; Followed by a line feed
  1100. chrou5: call    outprt
  1101.         ret
  1102.  
  1103.                                         ; these commands invoke Quit
  1104. cdos:   mov     al,'P'                  ; Push to DOS
  1105.         jmp     short cmdcom
  1106. cstatus:mov     al,'S'                  ; Status
  1107.         jmp     short cmdcom
  1108. cquit:  mov     al,'C'                  ; Exit Connect mode
  1109.         jmp     short cmdcom
  1110. cquery: mov     al,'?'                  ; Help
  1111.         jmp     short cmdcom
  1112. chang:  mov     al,'H'                  ; Hangup, drop DTR & RTS
  1113.         jmp     short cmdcom
  1114. cmdcom: mov     kbdflg,al               ; pass char to msster.asm via kbdflg
  1115.         stc                             ; signal that Quit is needed
  1116.         ret
  1117.  
  1118. dmpscn  proc    near                    ; dump screen to file
  1119.         call    savescr                 ; save screen to buffer
  1120.         call    dumpscr                 ; do buffer to file
  1121.         clc                             ; do not exit Connect mode
  1122.         ret
  1123. dmpscn  endp
  1124.  
  1125.  
  1126. ;[IU2] Routine to toggle VT100/VT52/Heath-19 modes in VT100 emulator.
  1127.  
  1128. vtans52 proc    near
  1129.         cmp     flags.vtflg,0           ; emulating?
  1130.         je      vtans5                  ; e = no
  1131.         call    ans52t                  ; Call MSZ toggle-it routine
  1132.         call    ansflg                  ; Update flags
  1133.         clc                             ; clear c bit so don't exit Connect
  1134. vtans5: ret
  1135. vtans52 endp
  1136.                                         ; Toggle Mode Line
  1137. trnmod: cmp     flags.modflg,1          ; mode line enabled and owned by us?
  1138.         jne     trnm2                   ; ne = no, don't touch it
  1139.         cmp     flags.vtflg,tttek       ; Tek mode?
  1140.         je      trnm2                   ; yes
  1141.         cmp     tekflg,0                ; Tek submode?
  1142.         jne     trnm2                   ; ne = yes, no mode line changes
  1143.         test    yflags,modoff           ; mode line already off?
  1144.         jnz     trnm1                   ; yes, go turn on
  1145.         call    clrmod                  ; no, clear mode line here
  1146.         or      yflags,modoff           ; turn on flag
  1147.         call    ansflg                  ; Update flags all around
  1148.         clc                             ; clear c bit so don't exit Connect
  1149.         ret
  1150. trnm1:  and     yflags,not modoff       ; Clear flag first
  1151.         cmp     flags.vtflg,0           ; terminal type of none?
  1152.         ja      trnm3
  1153.         push    dx                      ; scroll screen to save bottom line
  1154.         mov     ah,prstr                ; for terminal type none
  1155.         mov     dx,offset crlf
  1156.         int     dos
  1157.         pop     dx
  1158. trnm3:  call    modlin                  ; Then turn on mode line
  1159.         call    ansflg                  ; Update flags all around
  1160. trnm2:  clc
  1161.         ret
  1162.  
  1163. trnprs: push    ax                      ; toggle ^ PrtSc screen to printer
  1164.         test    anspflg,prtscr          ; are we currently printing?
  1165.         jnz     trnpr2                  ; nz = yes, its on and going off
  1166.         mov     ah,ioctl
  1167.         mov     al,7                    ; get output status of printer
  1168.         push    bx
  1169.         mov     bx,4                    ; file handle for system printer
  1170.         int     dos
  1171.         pop     bx
  1172.         jc      trnpr1                  ; c = printer not ready
  1173.         cmp     al,0ffh                 ; Ready status?
  1174.         je      trnpr2                  ; e = Ready
  1175. trnpr1: call    beep                    ; Not Ready, complain
  1176.         jmp     trnpr3                  ; and ignore request
  1177. trnpr2: xor     anspflg,prtscr          ; flip the flag
  1178.         test    yflags,modoff           ; mode line off?
  1179.         jnz     trnpr3                  ; nz = yes
  1180.         call    modlin                  ; else rewrite mode line
  1181. trnpr3: pop     ax
  1182.         clc                             ; return carry clear (don't quit)
  1183.         ret
  1184.  
  1185. ; Print on PRN the char in register al. On success return with C bit clear.
  1186. ; On failure do procedure pntchk and return its C bit (typically C set).
  1187. ; Uses buffer dumpbuf (screen dump).
  1188. pntchr  proc    near
  1189.         push    bx                      ; buffer the character
  1190.         mov     bx,pntptr               ; offset of next free byte in buffer
  1191.         mov     [bx],al                 ; store the character
  1192.         inc     bx                      ; update pointer
  1193.         mov     pntptr,bx               ; save pointer
  1194.         cmp     bx,offset dumpbuf+dumplen ; buffer full yet?
  1195.         pop     bx
  1196.         jb      pntchrx                 ; b = no, just return
  1197.         jmp     pntflsh                 ; go flush the buffer
  1198. pntchrx:clc                             ; clear carry bit
  1199.         ret
  1200. pntchr  endp
  1201.  
  1202. ; Flush printer buffer. Return carry clear if success.
  1203. ; On failure do procedure pntchk and return its C bit (typically C set).
  1204. ; Uses buffer dumpbuf (screen dump).
  1205. pntflsh proc    near
  1206.         cmp     pntptr,offset dumpbuf   ; any text in buffer?
  1207.         jne     pntfls1                 ; ne = yes
  1208.         ret                             ; else nothing to do
  1209. pntfls1:push    ax
  1210.         push    bx
  1211.         push    cx
  1212.         push    dx
  1213.         mov     bx,portval
  1214.         mov     bx,[bx].flowc           ; get flow control chars (bl=xoff)
  1215.         mov     flowon,bh
  1216.         mov     flowoff,bl              ; save for later
  1217.         mov     al,bl                   ; get flow control char
  1218.         cmp     al,0                    ; flow control active?
  1219.         je      pntfls2                 ; e = no, not using xoff
  1220.         call    prtbout                 ; output xoff (al), no echo
  1221. pntfls2:mov     ah,write2
  1222.         mov     bx,4                    ; file handle for DOS printer PRN
  1223.         mov     cx,pntptr               ; next free byte in buffer
  1224.         mov     dx,offset dumpbuf       ; start of buffer
  1225.         mov     pntptr,dx               ; reset buffer pointer
  1226.         sub     cx,dx                   ; cx = current byte count
  1227.         jcxz    pntfls3                 ; z = empty, do nothing
  1228.         int     dos                     ; write buffer to printer
  1229. pntfls3:pushf                           ; save carry status bit
  1230.         mov     al,flowon
  1231.         cmp     al,0                    ; flow control active?
  1232.         je      pntfls4                 ; e = no, not using xon
  1233.         call    prtbout                 ; output xon (al), no echo
  1234. pntfls4:popf
  1235.         pop     dx
  1236.         pop     cx
  1237.         pop     bx
  1238.         pop     ax
  1239.         jnc     pntflsx                 ; nc = success
  1240.         call    pntchk                  ; c = error (printer not ready)
  1241. pntflsx:ret
  1242. pntflsh endp
  1243.  
  1244. ; Check for PRN (DOS's printer) being ready. If ready, return with C clear
  1245. ; Otherwise, write Not Ready msg on mode line and return with C bit set.
  1246. ; N.B. DOS Critical Error will occur here if PRN is not ready.  [jrd]
  1247. pntchk  proc    near
  1248.         push    dx
  1249.         push    cx
  1250.         push    ax
  1251.         mov     cx,10                   ; ten retries before declaring error
  1252. pntchk0:mov     ah,ioctl                ; get printer status, via DOS
  1253.         mov     al,7                    ; status for output
  1254.         push    bx
  1255.         mov     bx,4                    ; std handle for DOS system printer
  1256.         int     dos
  1257.         pop     bx
  1258.         jc      pntchk1                 ; c = call failed
  1259.         cmp     al,0ffh                 ; code for Ready?
  1260.         je      pntchk3                 ; e = yes, assume printer is ready
  1261. pntchk1:push    cx                      ; save counter, just in case
  1262.         mov     ax,100                  ; wait 100 millisec
  1263.         call    pcwait
  1264.         pop     cx
  1265.         loop    pntchk0                 ; and try a few more times
  1266.                                         ; get here when printer is not ready
  1267.         test    yflags,modoff           ; is mode line off?
  1268.         jnz     pntchk2                 ; nz = off, skip msg
  1269.         push    bx
  1270.         push    si
  1271.         mov     si,offset pntmsg        ; say printer not ready
  1272.         mov     cx,pntmsgl              ; length
  1273.         call    modwrt                  ; write alternate mode line
  1274.         pop     si
  1275.         pop     bx
  1276. pntchk2:pop     ax
  1277.         pop     cx
  1278.         pop     dx
  1279.         stc                             ; say printer not ready
  1280.         ret
  1281. pntchk3:pop     ax
  1282.         pop     cx
  1283.         pop     dx
  1284.         clc                             ; say printer is ready
  1285.         ret
  1286. pntchk  endp
  1287.  
  1288. ;;;;; General screen management routines for IBM PC
  1289.  
  1290. ; computes screen location to ax, given row and col in [dh,dl], resp.
  1291.  
  1292. scrloc  proc    near
  1293.         mov     al,dh                   ; get row
  1294.         mul     crt_cols                ; multiply by number of columns
  1295.         add     al,dl                   ; plus current column number
  1296.         adc     ah,0                    ; ripple carry
  1297.         shl     ax,1                    ; double for attributes
  1298.         ret
  1299. scrloc  endp
  1300.  
  1301. ; Routine to set cursor type.  Pass cursor type in al: 0 = No cursor,
  1302. ; 1 = Underline cursor, 2 = Block cursor.   All cursors blink due to hardware.
  1303. ; Routine frags any ac that video ints frag.
  1304. ; For EGA boards running in non-25 line mode the cursor emulation is turned
  1305. ; off during cursor shape changing and restored afterward. It's another
  1306. ; ega Feature. [jrd]
  1307. ; Sense crt_mode 18h as Tseng Labs UltraPAK mono board in 132 column mode.
  1308. csrtype proc    near
  1309.         push    cx                      ; save the reg
  1310.         mov     ah,1                    ; Video fxn for set cursor type
  1311.         mov     cx,0F00H                ; Assume no cursor
  1312.         cmp     al,0                    ; No cursor?
  1313.         je      csrty2                  ; Right - set it and be done with it
  1314.         cmp     crt_mode,7              ; B&W card?
  1315.         je      csrty3                  ; Yes - different sizes
  1316.         cmp     crt_mode,18h            ; Tseng UltraPAK mono board?
  1317.         je      csrty3                  ; e = yes, use mono cursor
  1318.         mov     cx,0607H                ; No, use CGA underline cursor
  1319.         cmp     al,2                    ; Block?
  1320.         jne     csrty2                  ; No - set it now
  1321. csrty1: xor     ch,ch                   ; Yes - make it a block
  1322. csrty2: cmp     ega_mode,0              ; ega board active?
  1323.         je      csrty4                  ; e = no
  1324.         cmp     byte ptr low_rgt+1,23   ; standard screen length?
  1325.         je      csrty4                  ; e = yes, use regular cursor setting
  1326.         push    es                      ; EGA. turn off cursor emulation
  1327.         mov     ax,40h                  ; 40:87h is ega Info byte
  1328.         mov     es,ax
  1329.         push    es:[87h]                ; save Info byte around call
  1330.         or      byte ptr es:[87h],1     ; set emulation off (low bit = 1)
  1331.         mov     ah,1                    ; Video fxn for set cursor type
  1332.         int     screen
  1333.         pop     es:[87h]                ; restore Info byte
  1334.         pop     es                      ;  and our work register
  1335.         pop     cx
  1336.         ret
  1337. csrty4: int     screen                  ; regular cursor shape setting
  1338.         pop     cx
  1339.         ret
  1340. csrty3: mov     cx,0B0CH                ; Assume B&W underline cursor
  1341.         cmp     al,2                    ; Block?
  1342.         jne     csrty2                  ; No - set it now
  1343.         jmp     csrty1                  ; Yes - make it a block
  1344. csrtype endp
  1345.  
  1346.  
  1347. ; Save the entire screen in a buffer so we can restore and/or dump it.
  1348. ; Saves regular (80x25) screens to memory buffer scrsav and other sized
  1349. ; screens to video memory page 1. Resultant save place put into savadr
  1350. ; (offset then segment) and current low_rgt size info in savflg. Note,
  1351. ; some Environments (TopView/Windows etc) may not permit use of page 1. [jrd]
  1352. savescr proc    near
  1353.         push    es
  1354.         push    ds
  1355.         push    ax
  1356.         push    cx
  1357.         push    si
  1358.         push    di
  1359.         call    scrseg                  ; get screen segment in ax and es:di
  1360.         push    ax                      ; save screen segment
  1361.         mov     si,0
  1362.         mov     di,scrsav               ; place to put screen (memory buff)
  1363.         mov     savadr+2,di             ; working seg address for restore
  1364.         mov     savadr,0                ; and no offset for memory buffer
  1365.  
  1366.         call    scrmod                  ; ascertain video mode and screen
  1367.         mov     ax,low_rgt              ; text screen lower right (typ 23,79)
  1368.         mov     savflg,ax               ; save it for screen restore
  1369.         inc     al                      ; number of columns
  1370.         add     ah,2                    ;  plus status line = number of rows
  1371.         cmp     al,swidth               ; same as preset screen space (80)?
  1372.         ja      savsc1                  ; a = no, use screen video page 1
  1373.         cmp     ah,slen+1               ; same as preset screen length (24)?
  1374.         je      savsc3                  ; e = yes, use our memory buffer
  1375. savsc1: mul     ah                      ; times rows = characters on screen
  1376.         shl     ax,1                    ; times two for attributes = page 1
  1377.         mov     cx,ax                   ; cx = working copy of screen size
  1378.         and     cx,000fh                ; get lower four bits for offset part
  1379.         mov     savadr,cx               ; save offset in this word
  1380.         mov     cl,4
  1381.         shr     ax,cl                   ; compute number of paragraphs
  1382.         pop     di                      ; source screen address
  1383.         push    di                      ; restore again
  1384.         add     di,ax                   ; add paragraphs, point di to page 1
  1385.         mov     savadr+2,di             ; and save segment in this word
  1386. savsc3:
  1387.         mov     es,savadr+2             ; segment of storage area
  1388.         mov     di,savadr               ;  offset of same
  1389.         mov     ax,low_rgt              ; lower right of text screen
  1390.         inc     al                      ; number of columns on screen
  1391.         add     ah,2                    ; number of rows on screen
  1392.         mul     ah                      ; number of characters on the screen
  1393.         mov     cx,ax                   ; save this in counter cx
  1394.         call    scroff                  ; turn off screen [dt]
  1395.         pop     ds                      ; address screen
  1396.         cld
  1397.         rep     movsw                   ; save the screen
  1398.         pop     di
  1399.         pop     si
  1400.         pop     cx
  1401.         pop     ax
  1402.         pop     ds                      ; restore this
  1403.         call    scron                   ; turn on screen [dt]
  1404.         pop     es
  1405.         ret
  1406. savescr endp
  1407.  
  1408. ; restore screen from buffer (offset and seg in savadr, text coord in savflg).
  1409. ; Restores all screen lines. [jrd]
  1410. restscr proc    near
  1411.         push    es
  1412.         mov     ax,savflg               ; saved low_rgt text screen coord
  1413.         add     ah,2                    ; number of screen lines
  1414.         inc     al                      ; number of screen columns
  1415.         mul     ah                      ; columns time lines = # characters
  1416.         mov     cx,ax                   ; save this in counter cx
  1417.         push    cx                      ; save count
  1418.         call    scrseg                  ; get address of screen in es:di
  1419.         call    scroff                  ; turn off screen [dt]
  1420.         push    ds                      ; save original data segment
  1421.         mov     si,savadr               ; offset of storage area
  1422.         push    savadr+2                ; segment of same
  1423.         pop     ds                      ; put storage segment into ds
  1424.         cld
  1425.         rep     movsw                   ; restore data to screen
  1426.         pop     ds                      ; recover original data segment
  1427.         call    scron                   ; turn on screen [dt]
  1428.         pop     cx                      ; recover count
  1429.         call    scrsync                 ; synch Topview with new screen
  1430.         pop     es
  1431.         ret
  1432. restscr endp
  1433.  
  1434. ; Save the screen to a buffer and then append buffer to a disk file. [jrd]
  1435. ; Default filename is Kermit.scn; actual file can be a device too. Filename
  1436. ; is determined by mssset and is passed as pointer dmpname.
  1437. ; Dumpscr reads the screen image saved by savescr so call savescr call first.
  1438.  
  1439. dumpscr proc    near
  1440.         push    ax
  1441.         push    bx
  1442.         push    cx
  1443.         push    dx
  1444.         mov     dmphand,-1              ; preset illegal handle
  1445.         mov     dx,offset dmpname       ; name of disk file, from mssset
  1446.         mov     ax,dx                   ; where isfile wants name ptr
  1447.         call    isfile                  ; what kind of file is this?
  1448.         jc      dmp5                    ; c = no such file, create it
  1449.         test    byte ptr filtst.dta+21,1fh ; file attributes, ok to write?
  1450.         jnz     dmp0                    ; nz = no.
  1451.         mov     al,1                    ; writing
  1452.         mov     ah,open2                ; open existing file
  1453.         int     dos
  1454.         jc      dmp0                    ; c = failure
  1455.         mov     dmphand,ax              ; save file handle
  1456.         mov     bx,ax                   ; need handle here
  1457.         mov     cx,0ffffh               ; setup file pointer
  1458.         mov     dx,-1                   ; and offset
  1459.         mov     al,2                    ; move to eof minus one byte
  1460.         mov     ah,lseek                ; seek the end
  1461.         int     dos
  1462.         jmp     dmp1
  1463.  
  1464. dmp5:   test    filtst.fstat,80h        ; access problem?
  1465.         jnz     dmp0                    ; nz = yes
  1466.         mov     ah,creat2               ; file did not exist
  1467.         mov     cx,20h                  ; attributes, archive bit
  1468.         int     dos
  1469.         mov     dmphand,ax              ; save file handle
  1470.         jnc     dmp1                    ; nc = ok
  1471.  
  1472. dmp0:   mov     ah,3                    ; get cursor position
  1473.         xor     bx,bx                   ; page 0
  1474.         int     screen
  1475.         push    dx                      ; save it
  1476.         mov     dh,byte ptr low_rgt+1   ; go to status line
  1477.         inc     dh
  1478.         xor     dl,dl                   ; left most column
  1479.         mov     ah,2                    ; position cursor
  1480.         int     screen
  1481.         mov     dx,offset dmperr        ; say no can do
  1482.         mov     ah,prstr
  1483.         int     dos
  1484.         pop     dx                      ; get original cursor position
  1485.         mov     ah,2                    ; position cursor
  1486.         xor     bx,bx                   ; page 0
  1487.         int     screen
  1488.         pop     dx
  1489.         pop     cx
  1490.         pop     bx
  1491.         pop     ax
  1492.         clc
  1493.         ret
  1494.  
  1495. dmp1:   mov     ah,ioctl                ; is destination ready for output?
  1496.         mov     al,7                    ; test output status
  1497.         mov     bx,dmphand              ; handle
  1498.         int     dos
  1499.         jc      dmp0                    ; c = error
  1500.         cmp     al,0ffh                 ; ready?
  1501.         jne     dmp0                    ; ne = not ready
  1502.         push    di                      ; read screen buffer, write lines
  1503.         push    si
  1504.         push    es
  1505.         mov     cl,byte ptr low_rgt+1   ; number of lines - 2
  1506.         add     cl,2                    ; number of line on screen
  1507.         xor     ch,ch
  1508.         mov     si,savadr               ; offset in storage area
  1509. dmp2:   push    cx                      ; save outer loop counter
  1510.         mov     es,savadr+2             ; get storage segment
  1511.         mov     di,offset dumpbuf       ; data segment memory
  1512.         mov     cl,byte ptr savflg      ; number of columns on screen - 1
  1513.         inc     cl                      ; number of columns on screen
  1514.         xor     ch,ch
  1515. dmp3:   mov     ax,word ptr es:[si]     ; read char + attribute
  1516.         mov     byte ptr [di],al        ; store just char, don't use es:
  1517.         inc     si                      ; update pointers
  1518.         inc     si
  1519.         inc     di
  1520.         loop    dmp3                    ; do for each column
  1521.         std                             ; set scan backward
  1522.         mov     cl,byte ptr savflg      ; number of columns on screen - 1
  1523.         inc     cl                      ; number of columns on screen
  1524.         xor     ch,ch
  1525.         push    es
  1526.         mov     ax,ds
  1527.         mov     es,ax                   ; set es to data segment for es:di
  1528.         mov     di,offset dumpbuf       ; start of line
  1529.         add     di,cx                   ; plus length of line
  1530.         dec     di                      ; minus 1 equals end of line
  1531.         mov     al,' '                  ; thing to scan over
  1532.         repe    scasb                   ; scan until non-space
  1533.         cld                             ; set direction forward
  1534.         pop     es
  1535.         jz      dmp3a                   ; z = all spaces
  1536.         inc     cx
  1537.         inc     di
  1538. dmp3a:  mov     word ptr [di+1],0A0Dh   ; append cr/lf
  1539.         add     cx,2                    ; line count + cr/lf
  1540.         mov     dx,offset dumpbuf       ; array to be written
  1541.         mov     bx,dmphand              ; need file handle
  1542.         mov     ah,write2               ; write the line
  1543.         int     dos
  1544.         pop     cx                      ; get line counter again
  1545.         jc      dmp3b                   ; c = error
  1546.         loop    dmp2                    ; do next line
  1547.         mov     dx,offset dumpsep       ; put in formfeed/cr/lf
  1548.         mov     cx,3                    ; three bytes overall
  1549.         mov     ah,write2               ; write them
  1550. dmp3b:  mov     bx,dmphand              ; file handle
  1551.         int     dos
  1552.         mov     ah,close2               ; close the file now
  1553.         int     dos
  1554. dmp6:   pop     es
  1555.         pop     si
  1556.         pop     di
  1557.         pop     dx
  1558.         pop     cx
  1559.         pop     bx
  1560.         pop     ax
  1561.         clc
  1562.         ret
  1563. dumpscr endp
  1564.  
  1565.  
  1566. ; Get CRT mode - returns mode in variable crt_mode,
  1567. ; updates crt_cols and low_rgt.
  1568. ; For EGA active it looks in Bios work memory 40:84H for number of rows. [jrd]
  1569. scrmod  proc    near
  1570.         push    ax
  1571.         push    dx
  1572.         mov     ah,15                   ; Get current video state
  1573.         int     screen
  1574.         mov     crt_mode,al             ; Store CRT mode value
  1575.         mov     crt_cols,ah             ; store # of cols
  1576.         mov     dl,ah                   ; # of cols again
  1577.         mov     dh,crt_lins             ; and # of rows (constant from msster)
  1578.         cmp     ega_mode,0              ; ega active?
  1579.         je      scrmod4                 ; e = no
  1580.         push    es                      ; yes, permit different lengths
  1581.         mov     ax,40h                  ; refer to 40:84h for # ega rows
  1582.         mov     es,ax
  1583.         mov     ah,es:[84h]             ; get number of rows - 1 (typ 24)
  1584.         cmp     ah,20                   ; less than 20 rows?
  1585.         jb      scrmod3                 ; b = yes, ignore this length
  1586.         cmp     ah,80                   ; more than 80 rows?
  1587.         ja      scrmod3                 ; a = yes, ignore this length
  1588.         mov     dh,ah                   ; use this length
  1589.         mov     crt_lins,dh             ; update our working constant
  1590. scrmod3:pop     es
  1591. scrmod4:dec     dl                      ; max text column, count from zero
  1592.         dec     dh                      ; max text row, count from zero
  1593.         mov     low_rgt,dx              ; save away window address
  1594.         pop     dx
  1595.         pop     ax
  1596.         ret
  1597. scrmod  endp
  1598.  
  1599.  
  1600. ; Get screen segment - returns screen segment in ax, and full address in es:di
  1601.  
  1602. scrseg  proc    near
  1603.         xor     di,di                   ; start at beginning of screen (0,0)
  1604.         mov     ax,0B000H               ; Assume B&W card
  1605.         cmp     crt_mode,7              ; Is it?
  1606.         je      scrse1                  ; e = yes
  1607.         cmp     crt_mode,18h            ; Tseng UltraPAK mono in 132 col?
  1608.         je      scrse1                  ; e = yes, use seg B000H
  1609.         mov     ax,0B800H               ; No - video memory is here on color
  1610.         cmp     crt_mode,12             ; graphics set?
  1611.         jb      scrse1                  ; b = no
  1612.         cmp     crt_mode,18             ; end of ordinary 640x480 graphics
  1613.         ja      scrse1                  ; a = no, assume CGA segment
  1614.         mov     ax,0A000H               ; graphics
  1615. scrse1: mov     es,ax           ; tell Topview our hardware address needs
  1616.         mov     tv_segs,es              ; save our hardware screen address
  1617.         mov     tv_sego,di              ; segment and offset form
  1618.         mov     tv_mode,1               ; assume we're running under Topview
  1619.         mov     ah,tvhere               ; query Topview for its presence
  1620.         int     screen
  1621.         mov     ax,es                   ; get its new segment for screen work
  1622.         cmp     ax,tv_segs              ; same as hardware?
  1623.         jne     scrse2                  ; ne = no, we are being mapped
  1624.         cmp     di,tv_sego              ; check this too
  1625.         jne     scrse2          ; ne = no too. Use TV's work buf as screen
  1626.         mov     tv_mode,0               ; else no Topview or no mapping
  1627. scrse2: mov     tv_segs,es              ; save segment
  1628.         mov     tv_sego,di              ; and offset
  1629.         ret
  1630. scrseg  endp
  1631.  
  1632. ; Synchronize a Topview provided virtual screen buffer with the image
  1633. ; seen by the user. Requires cx = number of words written to screen
  1634. ; (char & attribute bytes) and es:di = ENDING address of screen write.
  1635. ; Changes ax and di.
  1636. scrsync proc    near
  1637.         cmp     tv_mode,0               ; Topview mode active?
  1638.         je      scrsyn1                 ; e = no, skip DOS call below
  1639.         sub     di,cx                   ; backup to start byte (cx = words)
  1640.         sub     di,cx                   ;  after storing words to screen
  1641.         mov     ah,tvsynch              ; tell Topview we have changed screen
  1642.         int     screen                  ;  so user sees updated screen
  1643. scrsyn1:ret
  1644. scrsync endp
  1645.  
  1646. ; The following two routines are used to turn off the display while we
  1647. ; are reading or writing the screen in one of the color card modes.
  1648. ; Turn screen off for (known) color card modes only. All regs preserved.
  1649. ; Includes code for old procedure scrwait. 16 June 1987 [jrd]
  1650. scroff  proc    near
  1651.         cmp     refresh,0               ; slow refresh?
  1652.         jne     scrofx                  ; ne = no wait
  1653.         cmp     ega_mode,0              ; Extended Graphics Adapter in use?
  1654.         jne     scrofx                  ; ne = yes, no waiting
  1655.         cmp     tv_mode,0               ; Topview mode?
  1656.         jne     scrofx                  ; ne = yes, no waiting
  1657.         cmp     crt_mode,7              ; B&W card?
  1658.         jnb     scrofx                  ; Yes - just return
  1659.         push    ax                      ; Save ax and dx
  1660.         push    dx
  1661.         mov     dx,crt_status           ; CGA: Wait for vertical retrace
  1662. scrof1: in      al,dx
  1663.         test    al,disp_enb             ; display enabled?
  1664.         jnz     scrof1                  ; yes, keep waiting
  1665. scrof2: in      al,dx
  1666.         test    al,disp_enb             ; now wait for it to go off
  1667.         jz      scrof2                  ; so can have whole cycle
  1668.         mov     dx,crtmset              ; Output to CRT mode set port
  1669.         mov     al,25H                  ; This shuts down the display
  1670.         out     dx,al                   ; Dumb, but card is too
  1671.         pop     dx                      ; restore regs
  1672.         pop     ax
  1673. scrofx: ret
  1674. scroff  endp
  1675.  
  1676.  
  1677. ; Turn screen on for (known) color card modes only
  1678. ; All registers are preserved.
  1679.  
  1680. scron   proc    near
  1681.         cmp     refresh,0               ; slow refresh?
  1682.         jne     scronx                  ; ne = no wait
  1683.         cmp     ega_mode,0              ; Extended Graphics Adapter in use?
  1684.         jne     scronx                  ; ne = yes, no waiting
  1685.         cmp     tv_mode,0               ; Topview mode?
  1686.         jne     scronx                  ; ne = yes, no waiting
  1687.         cmp     crt_mode,7              ; B&W card?
  1688.         jnb     scronx                  ; Yes - just return
  1689.         push    ax                      ; Save ax, dx, and si
  1690.         push    dx
  1691.         push    si
  1692.         mov     al,crt_mode             ; Convert crt_mode to a word
  1693.         xor     ah,ah
  1694.         mov     si,ax                   ; Get it in a usable register
  1695.         mov     al,msets[si]            ; Fetch the modeset byte
  1696.         mov     dx,crtmset              ; This port
  1697.         out     dx,al                   ; Flash it back on
  1698.         pop     si                      ; restore regs
  1699.         pop     dx
  1700.         pop     ax
  1701. scronx: ret
  1702. scron   endp
  1703.  
  1704.  
  1705. ; Screen clearing routine. [IU]
  1706. ;
  1707. ; Call:         ax/     coordinates of first screen location to be cleared.
  1708. ;               bx/     coordinates of last location to be cleared.
  1709. ; Coord: ah = row [0-24], al = column [0-79]. Preserves all registers. [jrd]
  1710.  
  1711. atsclr: push    ax                      ; save regs
  1712.         push    cx
  1713.         push    dx
  1714.         mov     dx,bx                   ; Compute last screen offset in ax
  1715.         push    ax
  1716.         call    scrmod                  ; update column length
  1717.         pop     ax                      ; scrmod zaps ax
  1718.         push    ax
  1719.         call    scrloc                  ; get screen start address in ax
  1720.         mov     cx,ax                   ; Save it in cx for a minute
  1721.         pop     dx                      ; Compute first screen offset in ax
  1722.         call    scrloc
  1723.         sub     cx,ax                   ; Compute number of locs to clear
  1724.         add     cx,2
  1725.         sar     cx,1                    ; Make byte count a word count
  1726.         jle     atscl2                  ; If nothing to clear, then vamos
  1727.         push    di                      ; save regs
  1728.         push    es                      ; save es
  1729.         push    ax                      ; save around call
  1730.         call    scrseg                  ; Get address of screen in ax, es:di
  1731.         pop     ax                      ; recover displacement
  1732.         add     di,ax                   ; displacement memory address
  1733.         mov     ah,scbattr              ; Use current screen background attr
  1734.         mov     al,' '                  ; Use space for fill
  1735.         mov     dl,byte ptr low_rgt     ; line length - 1
  1736.         inc     dl                      ; line length
  1737.         xor     dh,dh
  1738. ;;;;;   cmp     cx,dx                   ; Blanking a line or less??
  1739. ;;;;;   jg      atscl1                  ; No - make scroff disable display
  1740. atscl1: call    scroff                  ; Turn screen off if color card
  1741.         push    cx                      ; save word count for Topview
  1742.         cld
  1743.         rep     stosw                   ; Blit... (excuse PDP-10ese please)
  1744.         pop     cx                      ; recover word count
  1745.         call    scrsync                 ; synch Topview
  1746.         call    scron                   ; Turn screen back on if color card
  1747.         pop     es                      ; Restore segment register
  1748.         pop     di                      ; And destination index
  1749. atscl2: pop     dx                      ; restore regs
  1750.         pop     cx
  1751.         pop     ax
  1752.         ret
  1753.  
  1754. ; Scrolling routines.  vtscru scrolls up, vtscrd scrolls down 'scroll'
  1755. ; rows. The top line is saved in the circular buffer before scrolling up.
  1756. ; When running under an Environment control number of line positions moved
  1757. ; to be less than scrolling region. [jrd]
  1758. ; All registers are preserved.
  1759.  
  1760. ; Screen-roll down. Move text down one line, for terminal emulator only.
  1761.  
  1762. vtscrd: push    ax                      ; Upgraded by [jrd]
  1763.         push    bx
  1764.         push    cx
  1765.         push    dx
  1766.         mov     ah,7                    ; scroll down
  1767.         mov     ch,mar_top              ; top margin line
  1768.         mov     cl,0                    ; left most column
  1769.         mov     dh,mar_bot              ; bottom margin line
  1770.         mov     dl,byte ptr low_rgt     ; right most column
  1771.         mov     bh,scbattr              ; attributes
  1772.         mov     bl,dh
  1773.         sub     bl,ch                   ; region size - 1 line
  1774.         mov     al,scroll               ; number of lines to scroll, from msz
  1775. vscrd1: cmp     al,bl                   ; want to scroll more that than?
  1776.         jbe     vscrd2                  ; be = no
  1777.         push    ax
  1778.         mov     al,bl                   ; limit to region-1 for Windows
  1779.         int     screen                  ;  and do in parts
  1780.         pop     ax
  1781.         sub     al,bl                   ; get remainder
  1782.         jmp     short vscrd1            ; do next part
  1783. vscrd2: int     screen                  ; scroll it down
  1784.         pop     dx
  1785.         pop     cx
  1786.         pop     bx
  1787.         pop     ax
  1788.         ret
  1789.  
  1790. ; Screen scroll up one line (text moves up) for terminal emulator use.
  1791. ; When running under an Environment control number of line positions moved
  1792. ; to be less than scrolling region. [jrd]
  1793.  
  1794. vtscru: push    ax                      ; Upgraded by  [jrd]
  1795.         push    bx
  1796.         push    cx
  1797.         push    dx
  1798.         mov     cl,scroll               ; number of lines to scroll
  1799.         mov     ch,0
  1800.         jcxz    vscru3                  ; z = nothing to do
  1801.         cmp     mar_top,0               ; scrolling the top screen line?
  1802.         ja      vscru2                  ; a = no. don't save anything
  1803.         push    si
  1804.         push    di
  1805.         call    scroff                  ; turn off color screen
  1806.         mov     si,tv_sego              ; screen offset for es:si
  1807.         mov     bx,offset twnd          ; put lines in top window buffer
  1808. vscru1: push    cx                      ; save count
  1809.         call    putcirc                 ; put screen line in circular buffer
  1810.         pop     cx
  1811.         loop    vscru1                  ; save 'scroll' number of lines
  1812.         call    scron                   ; turn on screen again
  1813.         pop     di
  1814.         pop     si                      ; now scroll the visible screen
  1815. vscru2: mov     ah,6                    ; scroll up
  1816.         mov     dh,mar_bot              ; bottom row
  1817.         mov     dl,byte ptr low_rgt     ; right most column
  1818.         mov     ch,mar_top              ; top row of scrolling region
  1819.         mov     cl,0                    ; left most column
  1820.         mov     bh,scbattr              ; attributes
  1821.         mov     bl,dh
  1822.         sub     bl,ch                   ; region size - 1 line
  1823.         mov     al,scroll               ; number of lines to scroll, from msz
  1824. vscru2a:cmp     al,bl                   ; want to scroll more that than?
  1825.         jbe     vscru2b                 ; be = no
  1826.         push    ax
  1827.         mov     al,bl                   ; limit to region - 1 for Windows
  1828.         int     screen                  ;  and do in parts
  1829.         pop     ax
  1830.         sub     al,bl
  1831.         jmp     short vscru2a           ; do next part
  1832. vscru2b:int     screen                  ; scroll up that region
  1833. vscru3: pop     dx                      ; Restore the rest of the regs
  1834.         pop     cx
  1835.         pop     bx
  1836.         pop     ax
  1837.         ret
  1838.  
  1839. ;screen text roll up, version for manual scrolling only
  1840.  
  1841. mscru:  push    ax                      ; Upgraded by  [jrd]
  1842.         push    bx
  1843.         push    cx
  1844.         push    dx
  1845.         push    si
  1846.         push    di
  1847.         cmp     bwnd.lcnt,0             ; any lines in bottom window?
  1848.         je      mscru2                  ; e = no, so ignore request
  1849.         call    scroff                  ; turn off color screen
  1850.         mov     bx,offset twnd          ; this is where it goes
  1851.         mov     si,tv_sego              ; screen offset for es:si
  1852.         call    putcirc                 ; put screen line in circular buffer
  1853.         mov     ax,601H                 ; scroll up one line
  1854.         mov     dx,low_rgt              ; lower right corner
  1855.         xor     cx,cx                   ; top row of scrolling region
  1856.         mov     bh,scbattr              ; background attributes
  1857.         int     screen                  ; scroll up that region
  1858.         mov     dx,low_rgt
  1859.         mov     dl,0                    ; location is lower left corner
  1860.         call    scrloc                  ; get count from display start
  1861.         mov     di,ax
  1862.         push    es
  1863.         mov     bx,tv_segs              ; get screen's segment into, es:di
  1864.         mov     es,bx                   ; segment
  1865.         add     di,tv_sego              ; destination memory address (es:di)
  1866.         mov     bx,offset bwnd          ; source of lines
  1867.         call    getcirc                 ; get line from circ buf to screen
  1868.         pop     es                      ; restore es
  1869.         call    scron                   ; turn on the screen
  1870. mscru2: pop     di                      ; Restore the rest of the regs
  1871.         pop     si
  1872.         pop     dx
  1873.         pop     cx
  1874.         pop     bx
  1875.         pop     ax
  1876.         ret
  1877.  
  1878.  
  1879. ;screen text scroll down, for manual mode only
  1880. mscrd:  push    ax                      ; Upgraded by [jrd]
  1881.         push    bx
  1882.         push    cx
  1883.         push    dx
  1884.         push    si
  1885.         push    di
  1886.         cmp     twnd.lcnt,0             ; any lines left in top window?
  1887.         je      mscrd1                  ; e = no, ingore request
  1888.         call    scroff                  ; turn off screen
  1889.         mov     dx,low_rgt              ; from screen location, row
  1890.         mov     dl,0                    ; starting in col 0
  1891.         call    scrloc                  ; get offset in display buffer in ax
  1892.         mov     si,tv_sego              ; screen offset for es:di
  1893.         add     si,ax                   ; source addr in display buffer es:si
  1894.         mov     bx,offset bwnd          ; buffer to use (bottom window)
  1895.         call    putcirc                 ; copy bottom screen line to circ buf
  1896.         mov     ax,701H                 ; scroll down one line
  1897.         xor     cx,cx                   ; top left corner
  1898.         mov     dx,low_rgt              ; bottom right corner
  1899.         mov     bh,scbattr              ; attributes
  1900.         int     screen                  ; scroll it down
  1901.         push    es
  1902.         mov     di,tv_segs              ; screen segment
  1903.         mov     es,di
  1904.         mov     di,tv_sego              ; screen offset, for es:di
  1905.         mov     bx,offset twnd          ; buffer to use (top window)
  1906.         call    getcirc                 ; copy from circ buf to screen
  1907.         pop     es
  1908.         call    scron                   ; turn on display again
  1909. mscrd1: pop     di                      ; Restore the rest of the regs
  1910.         pop     si
  1911.         pop     dx
  1912.         pop     cx
  1913.         pop     bx
  1914.         pop     ax
  1915.         ret
  1916.  
  1917. ; move viewing window down as much as possible (text moves up)
  1918. endwnd  proc    near                    ; go to end of scrolling text
  1919.         push    cx
  1920.         mov     cx,bwnd.lcnt            ; all bottom window lines [dlk]
  1921.         jmp     dnwp0                   ; and enter dwnpg
  1922. endwnd  endp
  1923.  
  1924. dnone   proc    near                    ; move text up one line [jrd]
  1925.         push    cx
  1926.         mov     cx,1
  1927.         jmp     dnwp0
  1928. dnone   endp
  1929.  
  1930. ; scroll viewing window down (text moves up) one page (24 lines)
  1931. dnwpg   proc    near
  1932.         push    cx
  1933.         mov     cl,byte ptr low_rgt+1   ; number of rows, excl status
  1934.         inc     cl                      ; count from 1, not 0
  1935.         mov     ch,0
  1936. dnwp0:                                  ; additional entry point
  1937.         cmp     bwnd.lcnt,cx            ; enough lines in bottom line buffer?
  1938.         jge     dnwp1                   ; ge = we have that many lines stored
  1939.         mov     cx,bwnd.lcnt            ; do as many as we have
  1940. dnwp1:  jcxz    dnwp2                   ; z = nothing to do
  1941.         cmp     tekflg,0                ; Tek mode active?
  1942.         jne     dnwp2                   ; ne = yes, no scrolling
  1943.         call    mscru                   ; scroll up text one line
  1944.         loop    dnwp1
  1945. dnwp2:  pop     cx
  1946.         clc
  1947.         ret
  1948. dnwpg   endp
  1949.  
  1950. ; home viewing window
  1951. homwnd  proc    near
  1952.         push    cx
  1953.         mov     cx,twnd.lcnt            ; all top window lines [dlk]
  1954.         jmp     upwp0                   ; join upwpg
  1955. homwnd  endp
  1956.  
  1957. upone   proc    near                    ; move text down one line [jrd]
  1958.         push    cx
  1959.         mov     cx,1
  1960.         jmp     upwp0
  1961. upone   endp
  1962.  
  1963. ; scroll viewing window up (text moves down) a page (24 lines)
  1964. upwpg   proc    near
  1965.         push    cx
  1966.         mov     cl,byte ptr low_rgt+1   ; number of rows, excl status line
  1967.         inc     cl                      ; count from 1, not 0
  1968.         mov     ch,0
  1969. upwp0:                                  ; additional entry point
  1970.         cmp     twnd.lcnt,cx            ; enough lines in top line buffer?
  1971.         jae     upwp1                   ; ae = at least as many as requested
  1972.         mov     cx,twnd.lcnt            ; do only as many as are stored
  1973. upwp1:  jcxz    upwp2                   ; z = no lines to scroll
  1974.         cmp     tekflg,0                ; Tek mode active?
  1975.         jne     upwp2                   ; ne = yes, no scrolling
  1976.         call    mscrd                   ; roll down text one line
  1977.         loop    upwp1
  1978. upwp2:  pop     cx
  1979.         clc
  1980.         ret
  1981. upwpg   endp
  1982.  
  1983.  
  1984. ; Put a line into the circular buffer.  Pass the buffer structure in bx.
  1985. ; Source is tv_segs:si which is the current screen address.
  1986. ; Rewritten by [jrd]
  1987. putcirc proc    near
  1988.         push    es
  1989.         mov     cl,crt_cols             ; number of columns
  1990.         xor     ch,ch
  1991.         mov     es,[bx].orig            ; get segment of memory area
  1992.         cmp     bx,offset bwnd          ; bottom buffer?
  1993.         je      putci6                  ; e = yes
  1994.         mov     di,twnd.pp              ; pick up buffer ptr (offset from es)
  1995.         add     di,cx                   ; increment to next available slot
  1996.         add     di,cx                   ; char and attribute
  1997.         cmp     di,twnd.bend            ; would line extend beyond buffer?
  1998.         jb      putci1                  ; b = not beyond end
  1999.         mov     di,0                    ; else start at the beginning
  2000. putci1: mov     twnd.pp,di              ; update ptr
  2001.         cld                             ; set direction to forward
  2002.         push    ds                      ; save regular datas seg reg
  2003.         mov     ds,tv_segs              ; use screen segment for ds:si
  2004.         rep     movsw                   ; copy into buffer
  2005.         pop     ds                      ; restore regular datas segment
  2006.         mov     cx,twnd.lmax            ; line capacity of buffer
  2007.         dec     cx                      ; minus one work space line
  2008.         cmp     twnd.lcnt,cx            ; can we increment line count?
  2009.         jae     putci1b                 ; ae = no, keep going
  2010.         inc     twnd.lcnt               ; else count this line
  2011. putci1b:cmp     bwnd.lcnt,0             ; any lines in bottom buffer?
  2012.         je      putci2                  ; e = no
  2013.         mov     cx,bwnd.pp              ; see if we overlap bot buf
  2014.         cmp     cx,twnd.pp              ; is this line in bot buf area?
  2015.         jne     putci2                  ; ne = no
  2016.         add     cl,crt_cols             ; move bottom pointer one slot earlier
  2017.         adc     ch,0
  2018.         add     cl,crt_cols             ; words
  2019.         adc     ch,0
  2020.         cmp     cx,bwnd.bend            ; beyond end of buffer?
  2021.         jb      putci1a                 ; b = no
  2022.         mov     cx,0                    ; yes, start at beginning of buffer
  2023. putci1a:mov     bwnd.pp,cx              ; new bottom pointer
  2024.         dec     bwnd.lcnt               ; one less line in bottom buffer
  2025. putci2: pop     es
  2026.         ret
  2027. putci6:                                 ; bottom buffer
  2028.         add     cx,cx                   ; words worth
  2029.         cmp     bwnd.lcnt,0             ; any lines in the buffer yet?
  2030.         jne     putci7                  ; ne = yes
  2031.         mov     di,twnd.pp              ; get latest used slot of top buff
  2032.         add     di,cx                   ; where first free (?) slot starts
  2033.         cmp     di,bwnd.bend            ; are we now beyond the buffer?
  2034.         jb      putci6a                 ; b = no
  2035.         mov     di,0                    ; yes, start at beginning of buffer
  2036. putci6a:add     di,cx                   ; start of second free (?) slot
  2037.         cmp     di,bwnd.bend            ; are we now beyond the buffer?
  2038.         jb      putci6b                 ; b = no
  2039.         mov     di,0                    ; yes, start at beginning of buffer
  2040. putci6b:mov     cx,twnd.lmax            ; buffer line capacity
  2041.         sub     cx,twnd.lcnt            ; minus number used by top buffer
  2042.         sub     cx,2                    ; minus one work slot and one we need
  2043.         cmp     cx,0                    ; overused some slots?
  2044.         jge     putci8                  ; ge = enough to share
  2045.         add     twnd.lcnt,cx            ; steal these from top window beginning
  2046.         jmp     short putci8
  2047.  
  2048. putci7: mov     es,bwnd.orig            ; get segment of memory area
  2049.         mov     di,bwnd.pp              ; pick up buffer ptr (offset from es)
  2050.         cmp     di,0                    ; would line start before buffer?
  2051.         jne     putci7a                 ; ne = after start of buffer
  2052.         mov     di,bwnd.bend            ; else start at the end minus one slot
  2053.         inc     di
  2054. putci7a:sub     di,cx
  2055. putci8: mov     bwnd.pp,di              ; update ptr (this is latest used slot)
  2056.         mov     cl,crt_cols
  2057.         xor     ch,ch
  2058.         cld                             ; set direction to forward
  2059.         push    ds                      ; save regular datas seg reg
  2060.         mov     ds,tv_segs              ; use screen segment for ds:si
  2061.         rep     movsw                   ; copy into buffer
  2062.         pop     ds                      ; restore regular datas segment
  2063.         mov     cx,bwnd.lmax            ; line capacity of buffer
  2064.         cmp     bwnd.lcnt,cx            ; can we increment line count?
  2065.         jae     putci8b                 ; ae = no, keep going
  2066.         inc     bwnd.lcnt               ; else count this line
  2067. putci8b:cmp     twnd.lcnt,0             ; any lines in top line buf?
  2068.         je      putci9                  ; e = no
  2069.         mov     cx,twnd.pp              ; yes, see if we used last top line
  2070.         cmp     cx,bwnd.pp              ; where we just wrote
  2071.         jne     putci9                  ; not same place, so all is well
  2072.         dec     twnd.lcnt               ; one less line in top window
  2073.         cmp     cx,0                    ; currently at start of buffer?
  2074.         jne     putci8a                 ; ne = no
  2075.         mov     cx,twnd.bend            ; yes
  2076.         inc     cx
  2077. putci8a:sub     cl,crt_cols             ; back up top window
  2078.         sbb     ch,0
  2079.         sub     cl,crt_cols             ; by one line
  2080.         sbb     ch,0
  2081.         mov     twnd.pp,cx              ; next place to read
  2082. putci9: pop     es
  2083.         ret
  2084. putcirc endp
  2085.  
  2086. ; Get a line from the circular buffer, removing it from the buffer.
  2087. ; returns with carry on if the buffer is empty.
  2088. ; Pass the buffer structure in bx.
  2089. ; Destination preset in es:di which is the current screen address.
  2090. ; Rewritten by [jrd]
  2091. getcirc proc    near
  2092.         cmp     [bx].lcnt,0             ; any lines in buffer?
  2093.         jne     getci1                  ; ne = yes, ok to take one out
  2094.         stc                             ; else set carry
  2095.         ret
  2096. getci1:                                 ; top and bottom window common code
  2097.         mov     cl,crt_cols             ; # of chars to copy
  2098.         xor     ch,ch
  2099.         mov     si,[bx].pp              ; this is source
  2100.         push    si                      ; save around calls
  2101.         push    cx                      ; save around calls
  2102.         cld                             ; set direction to forward
  2103.         push    ds                      ; save original ds
  2104.         mov     ax,[bx].orig            ; use seg address of buffer for si
  2105.         mov     ds,ax
  2106.         rep     movsw                   ; destination = screen at es:di
  2107.         pop     ds                      ; recover original data segment
  2108.         pop     cx                      ; recover word count
  2109.         call    scrsync                 ; synch Topview
  2110.         pop     si                      ; get ptr again
  2111.         add     cx,cx                   ; words
  2112.         cmp     bx,offset bwnd          ; bottom window?
  2113.         je      getci7                  ; e = yes
  2114.         sub     si,cx                   ; top window, move back
  2115.         jnc     getci6                  ; nc = still in buffer, continue
  2116.         mov     si,twnd.bend            ; else use end of buffer
  2117.         sub     si,cx                   ; minus length of a piece
  2118.         inc     si
  2119. getci6: mov     twnd.pp,si              ; update ptr
  2120.         dec     twnd.lcnt               ; decrement # of lines in buffer
  2121.         clc                             ; make sure no carry
  2122.         ret
  2123. getci7:                                 ; bottom window
  2124.         add     si,cx                   ; words, move back (bot buf = reverse)
  2125.         cmp     si,bwnd.bend            ; still in buffer?
  2126.         jb      getci8                  ; b = yes
  2127.         mov     si,0                    ; else use beginning of buffer
  2128. getci8: mov     bwnd.pp,si              ; update ptr
  2129.         dec     bwnd.lcnt               ; decrement # of lines in buffer
  2130.         clc                             ; make sure no carry
  2131.         ret
  2132. getcirc endp
  2133.  
  2134. ;
  2135. ; CHKDSP - procedure to check for hardware support of 132 cols [dlk]
  2136. ;
  2137. ;  Supported hardware: EVA board from Tseng Labs w/132-col kit installed
  2138. ;               Tseng Labs UltraPAK mono/Herc board w/132 column modes.
  2139. ;               Video 7 Vega Deluxe w/ 132X25.COM driver installed [tmk]
  2140. ;               and VGA board, ATI EGA Wonder, Everex ev-659 and fvga-673.
  2141. ;  The routine checks for the presence of a 132-column-capable adapter. If
  2142. ;  one is found, its handler returns the proper video mode in [CX]. The main-
  2143. ;  line code then moves this to [AX] and issues the video interrupt.
  2144. ;
  2145. chgdsp  proc    near
  2146.         push    es                      ; save all we use
  2147.         push    ax
  2148.         push    bx
  2149.         push    cx
  2150.         push    dx
  2151.         push    si
  2152.         push    di
  2153.         mov     temp,ax                 ; save set/reset flag from msz
  2154.         mov     ah,flowoff              ; get xoff
  2155.         cmp     ah,0                    ; flow control?
  2156.         je      chgds0                  ; e = none
  2157.         call    outchr                  ; send it
  2158.          nop                            ; avoid serial port interrupts while
  2159.          nop                            ; doing many rep scasb's below
  2160.          nop
  2161.         call    savescr                 ; save current screen
  2162.         mov     ax,40                   ; wait 40 millisec before video tests
  2163.         call    pcwait                  ; so don't mix screen and port intrpts
  2164.  
  2165. chgds0: call    ckteva                  ; try Tseng Labs EVA
  2166.         jnc     chgds1                  ; nc = found
  2167.         call    ckv7vd                  ; try Video 7 EGA Deluxe and VGA
  2168.         jnc     chgds1                  ; nc = found
  2169.         call    ckatiw                  ; try ATI EGA Wonder
  2170.         jnc     chgds1                  ; nc = found
  2171.         call    ckevrx                  ; try Everex Micro Enhancer Deluxe
  2172.         jnc     chgds1                  ; nc = found
  2173.         call    ckevga                  ; try Everex EVGA-673
  2174.         jnc     chgds1                  ; nc = found
  2175.         jmp     chgdsx                  ; if not, exit
  2176.                                         ; Perform mode change
  2177. chgds1: mov     ax,cx                   ; get returned value in proper reg
  2178.         int     screen                  ; call the bios
  2179.         cmp     flags.modflg,1          ; is mode line enabled?
  2180.         jbe     chgds2                  ; be = yes, and off or locally owned
  2181.         mov     flags.modflg,1          ; remove foreign ownership
  2182. chgds2: call    scrini                  ; reset parameters
  2183. chgdsx: mov     ah,flowon               ; get flowon byte
  2184.         cmp     ah,0                    ; using flow control?
  2185.         je      chgdsx1                 ; e = no
  2186.         call    outchr                  ; send it
  2187.          nop
  2188.          nop
  2189.          nop
  2190. chgdsx1:pop     di                      ; restore what we saved
  2191.         pop     si
  2192.         pop     dx
  2193.         pop     cx
  2194.         pop     bx
  2195.         pop     ax
  2196.         pop     es
  2197.         ret                             ; return to caller
  2198. chgdsp  endp
  2199.  
  2200. ; Individual tests for various 132-column boards
  2201.                                         ;
  2202.                                         ; Tseng LABS EVA and UltraPAK
  2203. ckteva: mov     ax,0c000h               ; seg addr for EVA
  2204.         mov     es,ax                   ; set into es register
  2205.         mov     di,76h                  ; offset of board's string
  2206.         lea     si,tsngid               ; validation string
  2207.         mov     cx,tsnglen              ; length of validiation string
  2208.         cld
  2209.         repe    cmpsb                   ; compare strings
  2210.         je      ckteva2                 ; e = strings match
  2211.         mov     ax,4d00h                ; check for UltraPAK mono driver
  2212.         int     screen
  2213.         cmp     ax,5aa5h                ; driver signature?
  2214.         jne     chnoad                  ; ne = no
  2215.         mov     cx,7                    ; default to mono (7) for this board
  2216.         cmp     byte ptr temp,0         ; setting 132 columns?
  2217.         je      ckteva1                 ; e = resetting to normal
  2218.         mov     cx,18h                  ; set to 132 cols (Set Mode 18H)
  2219. ckteva1:clc                             ; carry clear means found
  2220.         ret
  2221.  
  2222. ckteva2:                                ; an EVA board - check for 132 col kit
  2223.         cmp     byte ptr es:099h,0      ; check 132 col kit installed
  2224.         je      chnoad                  ; e=0=not installed
  2225.         jmp     catfnd                  ; do the mode change
  2226.  
  2227. chnoad: stc                             ; indicate adapter not present
  2228.         ret                             ; and exit
  2229.                                         ;
  2230.                                         ; ATI EGA Wonder
  2231. ckatiw: mov     ax,0c000h               ; seg addr for EGA Wonder
  2232.         mov     es,ax                   ; set into es register
  2233.         mov     di,012fh                ; offset of message in ROM
  2234.         lea     si,atiwid               ; offset of message here
  2235.         mov     cx,atilen               ; length of validation string
  2236.         cld
  2237.         repe    cmpsb                   ; compare strings
  2238.         jne     chnoad                  ; ne = strings differ
  2239.                                         ;
  2240. catfnd: mov     cx,0003h                ; prepare to reset video mode
  2241.         cmp     byte ptr temp,0         ; are we setting or resetting?
  2242.         je      ckexit                  ; e is reset, exit
  2243.         mov     cx,0023h                ; set to 132 cols (Set Mode 23H)
  2244. ckexit: clc                             ; carry clear means found
  2245.         ret
  2246.                                         ;
  2247.                                         ; Video 7 Vega Deluxe
  2248. ckv7vd: mov     ax,0c000h               ; seg addr for Vega rom bios
  2249.         mov     es,ax                   ; set into es register
  2250.         mov     di,002ah                ; offset of message in ROM
  2251.         lea     si,vid7id               ; offset of message here
  2252.         mov     cx,vid7len
  2253.         cld
  2254.         repe    cmpsb                   ; compare strings
  2255.         je      cnv7fn0                 ; e = same
  2256.         mov     di,002ah                ; offset of ident string
  2257.         mov     si,offset vid7id2       ; Video 7 VGA board
  2258.         mov     cx,vid7len2
  2259.         repe    cmpsb
  2260.         je      cnv7fn2                 ; e = found
  2261. cnv7fx: jmp     chnoad                  ; ne = strings are different
  2262.                                         ;
  2263. cnv7fn0:test    byte ptr es:[03ffeh],1  ; is this a 'Deluxe' Vega?
  2264.         jz      chnoad                  ; z = nope, can't do it
  2265.         mov     ah,35h                  ; DOS Get Vector
  2266.         mov     al,10h                  ; Bios video interrupt
  2267.         int     dos                     ; get it into es:bx
  2268.         mov     di,bx                   ; es:bx is returned int 10h entry pnt
  2269.         sub     di,5ah                  ; back offset to msg in 132X25.COM
  2270.         lea     si,vid7id               ; offset of validation message
  2271.         mov     cx,vid7len              ; length of validation string
  2272.         cld
  2273. cnv7fn1:repe    cmpsb                   ; Look for repeat of msg by 132X25.COM
  2274.         jne     cnv7fn2                 ; if different
  2275.         mov     cl,crt_mode             ; prepare to reset video mode
  2276.         mov     ch,0
  2277.         cmp     byte ptr temp,0         ; are we setting or resetting?
  2278.         je      ckexit                  ; e is reset, exit
  2279.         mov     cx,0000h                ; set to 132 cols (old 40x25)
  2280.         jmp     short ckexit            ; and exit
  2281.  
  2282. cnv7fn2:mov     ax,6f00h                ; check for VegaBios driver
  2283.         int     screen
  2284.         cmp     bx,'V7'                 ; Video 7 Bios presence response
  2285.         jne     cnv7fx                  ; ne = not there
  2286.         mov     ax,6f01h                ; al gets monitor type (mono,color,ega)
  2287.         int     screen
  2288.         mov     bx,51h                  ; presume mono 132x25, page 0
  2289.         cmp     crt_lins,42             ; 43 lines active?
  2290.         jb      cnv7fn2a                ; b = no
  2291.         inc     bx                      ; use bx = 52h for 132x43
  2292. cnv7fn2a:
  2293.         cmp     al,10h                  ; analogue fixed freq (IBM 85xx)?
  2294.         je      cnv7fx                  ; e = yes, no 132 columns
  2295.         cmp     al,2                    ; 1 = mono, 2 = color, above = ega
  2296.         jb      cnv7fn3                 ; b = mono or unknown
  2297.         mov     bx,4fh                  ; presume med res color 132x25
  2298.         je      cnv7fn3                 ; e = med res color, al = 2
  2299.         mov     bx,41h                  ; ega high res 132x25, enhanced mons
  2300.         cmp     crt_lins,42             ; 43 lines active?
  2301.         jb      cnv7fn3                 ; b = no
  2302.         inc     bx                      ; use bx = 42h for 132x43
  2303. cnv7fn3:mov     ax,6f05h                ; set special mode found in bl
  2304.         cmp     byte ptr temp,0         ; resetting to 80 column mode?
  2305.         jne     cnv7fn4                 ; ne = no, setting 132x25
  2306.         mov     al,crt_norm             ; get normal mode
  2307.         mov     ah,0                    ; set mode
  2308.         cmp     crt_lins,42             ; 43 lines active?
  2309.         jb      cnv7fn4                 ; b = no
  2310.         mov     bl,40h                  ; use Video 7 mode 40h 80x43 for color
  2311.         mov     ax,6f05h                ; and do special mode set
  2312. cnv7fn4:int     screen                  ; special mode is in bl
  2313.         mov     cx,0f00h                ; a nop screen bios command
  2314.         clc
  2315.         ret
  2316.  
  2317. ckevrx: mov     ax,0c000h               ; seg addr for Everex EV-659
  2318.         mov     es,ax                   ; set into es register
  2319.         mov     di,0047h                ; offset of message in ROM
  2320.         lea     si,evrxid               ; offset of message here
  2321.         mov     cx,evrxlen              ; length of validation string
  2322.         cld
  2323.         repe    cmpsb                   ; compare strings
  2324.         jne     ckfnr2                  ; ne = strings differ
  2325.         mov     ah,crt_lins             ; we recognize either 44 or 25 rows
  2326.         cmp     ah,43                   ; equal to 44-1 rows?
  2327.         jne     ckfnr1                  ; ne = no
  2328.         mov     cx,0070h                ; Everex extended mode ident
  2329.         mov     bl,09h                  ; prepare to reset video mode to 80x44
  2330.         cmp     byte ptr temp,0         ; are we setting or resetting?
  2331.         je      ckfnr4                  ; e is reset, exit
  2332.         mov     bl,0bh                  ; 132x44
  2333.         jmp     ckexit
  2334. ckfnr1: cmp     ah,24                   ; equal to 25-1 rows?
  2335.         je      ckfnr3                  ; e = yes
  2336. ckfnr2: jmp     chnoad                  ; ne = no
  2337. ckfnr3: mov     cx,0003h                ; prepare to reset video mode
  2338.         cmp     byte ptr temp,0         ; are we setting or resetting?
  2339.         je      ckfnr4                  ; e is reset, exit
  2340.         mov     cx,0070h                ; Everex extended mode ident
  2341.         mov     bl,0ah                  ; 132x25
  2342. ckfnr4: jmp     ckexit
  2343. ckevga: mov     ax,0c000h               ; Everex FVGA-673, rom segment
  2344.         mov     es,ax
  2345.         mov     di,76h                  ; offset in rom for board's id string
  2346.         lea     si,evgid                ; id string
  2347.         mov     cx,evglen               ; length of id string
  2348.         cld
  2349.         repe    cmpsb                   ; do they match?
  2350.         jne     ckevg2                  ; ne = no
  2351.         mov     cx,3                    ; prepare to reset video mode
  2352.         cmp     byte ptr temp,0         ; setting or resetting mode?
  2353.         je      ckevg1                  ; e = resetting, exit
  2354.         mov     cx,0070h                ; mode for 132x25
  2355.         mov     bl,0ah                  ; Everex mode 0ah
  2356. ckevg1: clc
  2357.         ret
  2358. ckevg2: stc                             ; say board not found
  2359.         ret
  2360. ; Jumping to this location is like retskp.  It assumes the instruction
  2361. ;   after the call is a jmp addr.
  2362.  
  2363. RSKP    PROC    NEAR
  2364.         pop     bp
  2365.         add     bp,3
  2366.         push    bp
  2367.         ret
  2368. RSKP    ENDP
  2369.  
  2370. ; Jumping here is the same as a ret
  2371.  
  2372. R       PROC    NEAR
  2373.         ret
  2374. R       ENDP
  2375.  
  2376. code    ends
  2377.  
  2378. if1
  2379.         %out [End of pass 1]
  2380. else
  2381.         %out [End of assembly]
  2382. endif
  2383.  
  2384.         end
  2385.  
  2386.  
  2387.